/****************************************************************************
/*  F i l e   D a t a                                                        
/*                                                                           
/*  Module       : FileManager                                                   
/*  C.I. No.     :                                                           
/*  $Revision: 1.31 $
/*  $Date: 2005/03/20 18:17:24 $
/*  Belonging to :                                                           
/*               :                                                           
/*  $RCSfile: FT_MMSUManager_int.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: sebastiani $
/*               :                                                           
/****************************************************************************
/*  U p d a t i n g                                                          
/*                                                                           
/*  $Log: FT_MMSUManager_int.c,v $
/*  Revision 1.31  2005/03/20 18:17:24  sebastiani
/*  rawFlag old code cancelled under if 0
/*
/*  Revision 1.30  2005/03/06 14:54:16  sebastiani
/*  fix log
/*
/*  Revision 1.29  2005/02/21 08:58:28  sebastiani
/*  all log comments completed
/*
/*  Revision 1.28  2004/11/19 15:14:35  sebastiani
/*  PRH_EXTERN_{VAR,ARR,TABLE} removed and put them on the autogenerated parameter heeader file
/*
/*  Revision 1.27  2004/09/17 15:01:00  faber
/*  LU_INFN_LOG flags fixing
/*
/*  Revision 1.26  2004/09/10 15:27:05  sebastiani
/*  fixed TM CC
/*
/*  Revision 1.25  2004/08/26 16:54:07  sebastiani
/*  fix some bug
/*
/*  Revision 1.24  2004/08/02 12:15:21  sebastiani
/*  using hk_manager to access to tmtc
/*
/*  Revision 1.23  2004/07/28 09:03:01  sebastiani
/*  *** empty log message ***
/*
/*  Revision 1.22  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.21  2004/04/23 14:37:26  tassa
/*  ops fix compilation!
/*
/*  Revision 1.20  2004/04/23 14:16:02  tassa
/*  change for donwloading procedures vrl handling
/*
/*  Revision 1.19  2004/03/08 15:49:09  alfarano
/*  improved handling functions for FE
/*
/*  Revision 1.18  2004/03/05 14:07:14  sebastiani
/*   TM_piSendTC      (TM_VRL_START,1) moved in StartDownlink in the right place,after starting of DMA in order to avoid delay time at starting
/*
/*  Revision 1.17  2004/03/03 11:23:43  tassa
/*  Start downlink manager by timer+message
/*
/*  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/11/28 14:49:46  sebastiani
/*  in MMSU delete comment lines
/*  in KHB fix HW bug
/*  in TS_PamManager add test
/*
/*  Revision 1.14  2003/11/18 09:01:14  alfarano
/*  laben patch fixes some problems
/*
/*  Revision 1.13  2003/11/13 16:05:18  sebastiani
/*  main_spare managerment
/*
/*  Revision 1.12  2003/11/11 15:13:39  faber
/*  commands for VRL/TMTC use now the INFN style wrapped identifiers
/*
/*  Revision 1.11  2003/11/05 08:17:19  sebastiani
/*  History Entry6 substituted with INFN style log
/*
/*  Revision 1.10  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.9  2003/10/27 18:50:24  sebastiani
/*  *** empty log message ***
/*
/*  Revision 1.8  2003/10/21 16:09:12  alfarano
/*  LU_LOG_INFN replacement for all remaining original log functions
/*
/*  Revision 1.7  2003/10/17 08:25:48  sebastiani
/*  FILE1 bugfixes,
/*  downlink various bugfixes, VRL switch on/off introduced,
/*  FT_ifStopDownLink_CallBack function introduced,
/*  "case" FT_STOP_DOWNLINK introduced for the MSSUManager task
/*
/*  Revision 1.6  2003/09/10 14:10:58  laben
/*  Fix Timer to ticks.
/*
/*  Revision 1.5  2003/09/10 13:44:00  laben
/*  New File System model: just one file used like a circular buffer.
/*  NEw donwlink procedure: downlink next sector until the timer expires.
/*
/*  Revision 1.4  2003/08/27 09:49:17  wizard
/*  Fix last sector in donwload.
/*  Set Sector size to 1024*1015
/*  Fix Donwload procedure... ( set size set lastsector flag.....)
/*  bye
/*
/*  Revision 1.3  2003/08/07 08:44:14  wizard
/*  SIMULATOR bugs ifdef/ifndef corrected
/*  laben bug "GetFileInfo" for FS_ERC32 id accepted in order to fix SM_pi_GetPacket
/*
/*  Revision 1.1.1.1  2003/08/04 09:40:21  sebastiani
/*  Imported sources laben rel. 19.06.2003 integrated with pam2
/*
/*  Revision 1.20  2003/06/09 10:23:22  aurora
/*  improved the management of data acquisition
/*
/*  Revision 1.19  2003/06/06 09:41:50  aurora
/*  fixed the latchup recovery function
/*
/*  Revision 1.18  2003/05/20 07:48:17  aurora
/*  correct the downlink mcmd when some parameter is wrong.
/*  The acquisition mode is restored only when the mcmd is executed.
/*
/*  Revision 1.17  2003/04/29 13:22:40  aurora
/*  cleared the last field of entry 6 for memory test
/*
/*  Revision 1.16  2003/04/11 08:24:55  aurora
/*  Fixed Memory Module TEST
/*
/*  Revision 1.15  2003/01/22 13:55:10  aurora
/*  typo
/*
/*  Revision 1.14  2002/11/20 13:56:48  zulia
/*  The ABORT S2M now run always
/*
/*  Revision 1.13  2002/11/14 09:48:31  zulia
/*  removed unsed code
/*
/*  Revision 1.12  2002/10/17 10:05:18  zulia
/*  fixed ON/OFF memory module
/*  optimised PIFReset
/*
/*  Revision 1.11  2002/07/31 14:27:00  zulia
/*  Correct EXE_MEM_CONF and init memory module
/*
/*  Revision 1.10  2002/07/29 09:03:53  zulia
/*  new downlink format
/*
/*  Revision 1.9  2002/05/09 13:43:49  aurora
/*  Modified for column latchup recovery
/*  Latchup retry added during column switch
/*
/*  Revision 1.8  2002/05/09 08:16:34  zulia
/*  *  acceptance release
/*
/*                                                                           
/*****************************************************************************/

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



#include <src/INFN/LU_SourceFileID_INFN.h>
#define __FILEID__ _FT_MMSUManager_int__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/LU_SourceFileID_INFN.h>


#include <src/INFN/LU_LogUtility_INFN.h>
  
#include <src/FileManager/MMSUManager/FT_MMSUManager_int.h>
#include <src/INFN/MH_ModeHandler_INFN.h>
#include <src/SRAMManager/SRAMPageManager/SM_SRAMPageManager_p.h>
#include <src/TM_TCManager/TMTCManager/TM_TMTCManager_p.h>
#include <src/INFN/OS_rtems_INFN_p.h>
#include <src/INFN/PM_PamManager_INFN.h>
#include <src/INFN/HK_Manager_INFN.h>


/*============================== Local Variables ============================*/

// FROM BRANCH_TM_SAMARA 
UINT32 FT_main_spare = FT_VRL_MAIN;

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

/*======= M M S U M a n a g e r   I N T E R N A L   F U N C T I O N S =======*/

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

/*****************************************************************************/
/* @Function: FT_ifSndMsgMMSUManager                                         */
/* @Purpose :                                                                */
/*  The function formats a message, then sends it to the MMSUManager task in */
/*  order to execute a specific operation.                                   */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  Code                 IN      Task operation code                         */
/*  Info                 IN      Task operation parameter                    */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/
    
status_code FT_ifSndMsgMMSUManager(unsigned int Code, unsigned int Info)
{
status_code status;
MsgTsk      sndMsg;

    /* Message code                      */
    sndMsg.Code =Code;   
    /* Operation parameter               */
    *(unsigned int* )&sndMsg.Info =Info;
    /* Size of parameter                 */
    sndMsg.LlInfo =sizeof(unsigned int);
    /* Send message to MMSUManager       */
    status =FT_piSndMsgMMSUManager(&sndMsg);
    return (status);
}


/*****************************************************************************/
/* @Function: FT_ifMCMDExeMemConf                                            */
/* @Purpose :                                                                */
/*  The function menages the EXE MEM CONF execution. The MCMD information    */
/*  are extracted from the buffer and inserted in the EXE MEM CONF MCMD      */
/*  structure.                                                               */
/*  The buffer is deleted from the partition. The Memory Module is switched  */
/*  ON or OFF in accordance with the MCMD switched flag parameter.           */
/*  To switch ON the module  are performed the following actions:            */
/*      -  Check if all two Module are OFF.                                  */
/*      -  Check if Memory Module to switch ON is OK.                        */
/*      -  Sending a log to the History area to notify the EXE MEM CONF MCND */
/*         execution.                                                        */
/*  To switch OFF the module  are performed the following actions:           */
/*      -  Sending a log to the History area to notify the EXE MEM CONF MCND */
/*         execution.                                                        */
/*  Any error detected during EXE MEM CONF initialization causes the MCMD    */
/*  rejection. A specific log sent to the HistoryArea object, defines the    */
/*  reason of the failure.                                                   */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  PtrMcmd              IN      Pointer to MCMD header                      */
/*                               (MA_HEADER_MCMD type)                       */
/*  MMSUStatus           IN      Pointer to all MMSU status structure        */
/*                               (FT_ALL_MMSU_STATUS type)                   */
/* @@                                                                        */
/*****************************************************************************/

void FT_ifMCMDExeMemConf (MA_HEADER_MCMD*    PtrMcmd,
                          FT_MMSU_STATUS*    MMSUStatus,
                          FT_RW_CH* ptrRWChannel)
{
status_code     status;    
unsigned short* pMcmdInfo;
unsigned int    timetagFlag;
unsigned int    param;
unsigned int    module;
unsigned int    memModSw;
unsigned int    memModOn;
unsigned int    i;

    /* Extract MCMD parameters and delete it from partition   */
    pMcmdInfo   =(unsigned short* )PtrMcmd->PtrMCMD;
    param  =*(pMcmdInfo+OFFSET_HEADER);
    module   =(param & FT_MM_SEL) ? FT_MEM_MOD_2 : FT_MEM_MOD_1;
    memModSw =param & FT_MM_SW;
    timetagFlag =(*(pMcmdInfo+1)&TIMETAG_MASK) ? TIMETAG_MCMD : IMMEDIATE_MCMD;
    MA_piDelBufferMCMD(PtrMcmd->PtrMCMD,timetagFlag);

    /* Check if Memory Module must be switched ON or OFF      */
    if (memModSw)
    {
        /* Check if possible switch ON the Memory Module      */ 
        /* Switch ON the Memory Module if Nominal and         */
        /* Redounded  is OFF and Module to switch is OK       */
        if (MMSUStatus->Module[FT_MEM_MOD_1].Mode==FT_MODE_MEM_MOD_OFF && 
            MMSUStatus->Module[FT_MEM_MOD_2].Mode==FT_MODE_MEM_MOD_OFF )
        {
            status =SUCCESSFUL;
            MMSUStatus->Module[module].State = FT_STATE_MOD_OK;
        }
        else
        {
            /* Define error type                              */
            status = HA_E2_ONE_MEM_MODULE_ON;
        }
    }
    else
    {
        /* It's always possible switch OFF the Module         */ 
        status =SUCCESSFUL;
    }

    /*=============== Entry 2 Log in History Area ============*/
    // LO G_INFN  HA_piLogHistoryEntry2 (PtrMcmd->Type,status);    
    /*@LOG MCMD MemExeConf - status */
    LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
    if (status == SUCCESSFUL)
    {
        if (memModSw)
        {
            /*=========== Memory Module is switched ON =======*/

            /* Memory Module ON                               */
            if ( FT_opMemModuleON(module) == SUCCESSFUL )
            	FT_ifRWChannelInit(ptrRWChannel, module, &MMSUStatus->Module[module]);

        }
        else
        {
            /*========== Memory Module is switched OFF =======*/
            /* Delete all file that using the Module into FAT */
            /* and mark as unused the sectors in the Free List*/
            /* Memory Module OFF                              */
            FT_opMemModuleOFF(module);
        }
    }
}



/*****************************************************************************/
/* @Function: FT_ifMCMDBiteExec                                              */
/* @Purpose :                                                                */
/*  The function menages the Bite MCMD execution. The MCMD Bite information  */
/*  are extracted from the buffer and inserted in the Bite MCMD structure.   */
/*  The buffer is deleted from the partition. To begin the Bite operations   */
/*  are performed the followings actions:                                    */
/*      -  Checking of the MCMD Bite parameters.                             */
/*      -  Program Dramma REINIT and SCRUBBING and REFRESH registers.        */
/*      -  Interrupt SFT_OVL and HW_OR,HW_AND masked.                        */
/*      -  Interrupt SA_OVL and LATCHUP_MONITOR enabled.                     */
/*      -  Starting of the Memory Module fill.                               */
/*      -  Sending a log to the History area to notify the Bite starting     */
/*         operations.                                                       */
/*  Any error detected during Biteinitialization causes the MCMD rejection.  */
/*  A specific log sent to the HistoryArea object, defines the reason of the */
/*  failure.                                                                 */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  PtrMcmd              IN      Pointer to MCMD header                      */
/*                               (MA_HEADER_MCMD type)                       */
/*  MMSUStatus           IN      Pointer to all MMSU status structure        */
/*                               (FT_MMSU_STATUS type)                       */
/*  TestStatus           IN      Pointer to test statuts structure           */
/*                               (FT_TEST_MOD_STATUS type)                   */
/*  status_code          OUT     Return code                                 */
//* @@                                                                       */
/*****************************************************************************/

status_code  FT_ifMCMDBiteExec (MA_HEADER_MCMD*      PtrMcmd, 
                                FT_MMSU_STATUS*      MMSUStatus,
                                FT_TEST_MOD_STATUS*  TestStatus,
                                FT_RW_CH*            PtrRWChannel)
{
status_code      status = HA_E2_MCMD_OK;
unsigned short*  pMcmdInfo;
unsigned int     initPattern;
unsigned int     boardId;
unsigned int     timetagFlag;
unsigned int     i;
FT_MEM_MOD*      pMemMod;

    /* Extract parameters and delete MCMD from partition  */
    pMcmdInfo   =(unsigned short* )PtrMcmd->PtrMCMD;

    initPattern = (UINT32)(*(pMcmdInfo+OFFSET_HEADER));

    /* Delete MCMD from partition                         */
    timetagFlag =(*(pMcmdInfo+1)&TIMETAG_MASK) ? TIMETAG_MCMD : IMMEDIATE_MCMD;
    MA_piDelBufferMCMD(PtrMcmd->PtrMCMD,timetagFlag);

    /* Perform a BITE only if the memory module is ON */
    /* and no BITE is in progress                     */
    if(PtrRWChannel->PtrModuleStatus->Mode != FT_MODE_MEM_MOD_ON)
    {
      if(PtrRWChannel->PtrModuleStatus->Mode == FT_MODE_MEM_MOD_BITE)
      {
        status = HA_E2_BT_RUNNING;
      }
      else
      {
        status = HA_E2_MOD_NOT_AVAILABLE;
      }
    }
    if (status == HA_E2_MCMD_OK)
    {
      boardId = PtrRWChannel->ActiveModule;
      /* Start the timeout timer for the BITE operation */
      status = OS_piStartTimer(FT_TIM, FT_BITETO,
                             FT_ifBiteTORecovery, (void*)PtrRWChannel);
      if (status != SUCCESSFUL)
      {
        /* Timer not started correctly           */
        // LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_FS,HA_E10_TIMER_ERR,status);
	/*@LOG error starting timer for bite operation - status */
	LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
        status =HA_E2_INTERNAL_ERR;
      }
    }
    if (status == HA_E2_MCMD_OK)
    {
        /* Program Dramma REINT register                  */
        FD_piDrammaWrWPBUSReg (boardId,FD_REINIT,0);
        /* Program Dramma SCRUBBING and REFRESH register  */
        FD_piDrammaWrWPBUSReg (boardId,FD_SCRUBBER_REFRESH,FD_SCRABBER_REFRESH_VALUE);
        /* Interrupt masked: SFT_OVL,HW_OR,HW_AND         */
        /* Interrupt unmask: SA_OVL,LATCHUP_MONITOR       */
        FD_piDrammaWrWPBUSReg(boardId,FD_INTMSK,FD_MM_INT_ABIL_SA);
        /* Clear all memory module interrupts             */     
        status =FD_piDrammaWrWPBUSReg(boardId,FD_INTCLR,FD_MM_INT_ALL);
        /* Start Memory module fix pattern filling        */
        initPattern |= FD_INITREG_START | FD_INITREG_INIT_MEM;
        status =FD_piDrammaWrWPBUSReg(boardId,FD_INITREG,initPattern);

        /* Set in MMSU status Module in BITE mode         */
        MMSUStatus->Module[boardId].Mode =FT_MODE_MEM_MOD_BITE;
        
        /* Set variable in Module Test Status             */
        TestStatus->State   =FT_TEST_START; 
        TestStatus->Module  =boardId;
        TestStatus->TestIdx =0;

        /*============= Entry 2 Log in History Area ==========*/
        // LOG_INFN HA_piLogHistoryEntry2 (PtrMcmd->Type,status);
	/*@LOG BITE: trace - status */
	LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
        /*========= Entry 0 Log in History Area ==========*/
        // LOG_INFN HA_piLogHistoryEntry0(HA_E0_STARTING,HA_E0_BITE,HA_E0_BITE_BIT);
	/*@LOG BITE: trace */
	LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,HA_E0_BITE_BIT);
    }
    else
    {
      /*============= Entry 2 Log in History Area ==========*/
      // LOG_INFN HA_piLogHistoryEntry2 (PtrMcmd->Type,status);
      /*@LOG BITE: trace - status */
      LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
    }

    return(status);
}




/*****************************************************************************/
/* @Function: FT_ifColLatchUpInter                                           */
/* @Purpose :                                                                */
/*  The function sends a message to the MMSUManager task to menage the       */
/*  latchup recovery procedure.                                              */
/*  The lactchup recovery information are compacted in an unsigned int type  */
/*  as follows :                                                             */
/*  32                               16                7               0     */
/*                                   Latchup columns   | Memory Module       */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  MemModule            IN      Memory Module (FT_MEMORY_MODULE type)       */
/*  LatchUpCol           IN      Latchup recovery information                */     
/* @@                                                                        */
/*****************************************************************************/

void FT_ifColLatchUpInter (unsigned int MemModule,
                           unsigned int LatchUpCol)
{

    /* Send message to the MMSUManager to start Latchup rocovery procedure   */
    FT_ifSndMsgMMSUManager(FT_LATCHUP_RECOVERY,FT_LATCHUP_INFO(MemModule,LatchUpCol));
}



/*****************************************************************************/
/* @Function: FT_ifLatchUpRecovery                                           */
/* @Purpose :                                                                */
/*  The function performs the latchup recovery procedure.                    */
/*  The actions executed to recovery the columns in latchup are the          */
/*  following:                                                               */
/*      - The memory module, and columns in error are extracted from         */
/*        the recovery information parameter.                                */
/*      - Abort all the operational modes that using the Memory Module in    */
/*        fail.                                                              */
/*      - Calling the columns latchup recovery procedure.                    */
/*      - If there is 1 column in error, calling the procedure to switch the */
/*        fail column with the spare column if available. If the column      */
/*        switch is ended correctly, the column in error is marked as FAIL   */
/*        and the spare  column is marked as USED into the MMSU status       */
/*        structure.                                                         */
/*   If the columns latchup procedure is missed the Memory Module is marked  */
/*   as fail, all the files that using the module is marked as corrupt, and  */
/*   the sectors of the module located into the free list is marked as       */
/*   unused.                                                                 */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  RecoveryInfo         IN      Recovery information                        */
/*  MMSUStatus           IN      Pointer to all MMSU status structure        */
/*                               (FT_ALL_MMSU_STATUS type)                   */
/*  PtrRWChannel         IN      Pointer to the Read/Write channels structure*/
/* @@                                                                        */
/*****************************************************************************/

void FT_ifLatchUpRecovery (unsigned int    RecoveryInfo,
                           FT_MMSU_STATUS* MMSUStatus,
                           FT_RW_CH*       PtrRWChannel)
{
status_code   status;    
unsigned int  memModule;
unsigned int  latchupBit;
unsigned int  colError;
unsigned int  pendingVal;
FT_MEM_MOD*   pM;
unsigned int  maskCol;
unsigned int  i;
SM_ACQMODE    acqMode;
FT_STR_MODE   currentStore;

    /* Get LatchUp recovery information                            */
    memModule  = FT_LATCHUP_MEM_MOD(RecoveryInfo);
    latchupBit =FT_LATCHUP_BIT(RecoveryInfo);
    pM         =&MMSUStatus->Module[memModule];
    
    /* Call column Latchup recovery procedure                      */
    status =FT_ifColumnLatchUp(memModule,FD_CONFIG_REG_27_11_B,
                               latchupBit,TRUE,&colError,&pendingVal);

    /* Abort a running Downlink */
    if(PtrRWChannel->ReadMode != FT_CLOSED)
    {
      FT_ifDownlinkAbort(PtrRWChannel);
    }
    /* Disable data acquisition nad storage in the mass memory */
    acqMode = PM_pi_GetAcqMode();
    PM_pi_SetAcqMode(SM_IDLE);
    currentStore = PtrRWChannel->StoreEnable;
    FT_ifDisableStore(PtrRWChannel, TRUE);
    if (status==SUCCESSFUL && colError)
    {
        /* There is 1 column in error, try to use the spare column */
        if ((status=FT_ifColumnSwitch(memModule,colError))==SUCCESSFUL)
        {
            /* Update column information                           */
            for (i=0,maskCol=1; i<FD_MAX_COLUMN_ENABLE; i++,maskCol <<=1)
            {
                if (colError & maskCol)
                {
                    pM->Column[i] =FT_COLUMN_FAIL;
                    break; /* Column set fail, exit from the loop  */
                }
            }
            pM->Column[FT_SPARE_COL] =FT_COLUMN_ON;
        }
    }
    /* Check if latchup procedure is OK                            */
    if (status!=SUCCESSFUL)
    {
        /* Latchup procedure is NOT OK                             */
        /* Memory Module is marked fail                            */
        pM->State =FT_STATE_MOD_FAIL;
        /*============= Entry 11 Log in History Area ==============*/
	// LOG_INFN  HA_piLogHistoryEntry11(HA_E11_MEMORY_MODULE,HA_E11_MOD_LATCHUP_REC_ERR,memModule, colError);
	/*@LOG LatchUpRecovery - status */
	LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,colError);
    }
    /* Disable the storage in the mass memory */
    if(currentStore != FT_STR_NONE)
    {
      FT_ifEnableStore(PtrRWChannel);
      PM_pi_SetAcqMode(acqMode);
    }
}



/*****************************************************************************/
/* @Function: FT_ifHwErrorInter                                              */
/* @Purpose :                                                                */
/*  The function sends a message to MMSUManager task to menage the hardware  */
/*  error recovery procedure.                                                */
/*  The hardware error information are compacted in an unsigned int type     */
/*  as follows :                                                             */
/*  32                               16                7               0     */
/*                                                     | Memory Module       */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  MemModule            IN      Memory Module (FT_MEMORY_MODULE type)       */
/* @@                                                                        */
/*****************************************************************************/

void FT_ifHwErrorInter (unsigned int MemModule)
{

    /* Send message to MMSUManager to start HW error rocovery menagement  */
    FT_ifSndMsgMMSUManager(FT_HW_ERROR_RECOVERY,MemModule);
}


/*****************************************************************************/
/* @Function: FT_ifHwErrorRecovery                                           */
/* @Purpose :                                                                */
/*  The function performs the Memory Module hardware error (HW) recovery     */
/*  procedure.                                                               */
/*  The actions executed to recovery the Memory Module HW error are the      */
/*  following:                                                               */
/*      - Extract the memory module information from the                     */
/*        -RecoveryInfo- parameter.                                          */
/*      - Masking of the Memory Module interrupts.                           */ 
/*      - Abort all the operational modes that using the Memory Module in    */
/*        fail.                                                              */
/*      - The memory module is marked as fail, all the files that using the  */
/*        module are marked as corrupt, the sectors of the module located    */
/*        into the free list are marked as unused.                           */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  RecoveryInfo         IN      Recovery information                        */
/*  MMSUStatus           IN      Pointer to all MMSU status structure        */
/*                               (FT_ALL_MMSU_STATUS type)                   */
/*  PtrRWChannel         IN      Pointer to the Read/Write channels structure*/
/* @@                                                                        */
/*****************************************************************************/

void  FT_ifHwErrorRecovery (unsigned int    RecoveryInfo,
                            FT_MMSU_STATUS* MMSUStatus,
                            FT_RW_CH*       PtrRWChannel)
                            
{
status_code   status;    
unsigned int  MemModule;
FT_MEM_MOD*   pM;
unsigned int  hwErr;
unsigned int  failed_col_num;
unsigned int  failed_col_bit;
unsigned int  pendingVal;
unsigned int  colEnable;
unsigned int  configRegVal;

    /* Get LatchUp recovery information                        */
    MemModule  = RecoveryInfo;
    pM         =&MMSUStatus->Module[MemModule];

    /* Mask all memory module interrupts                       */
    FD_piDrammaWrWPBUSReg(MemModule,FD_INTMSK,FD_MM_INT_ALL);

    /* Abort a running Downlink */
    if(PtrRWChannel->ReadMode != FT_CLOSED)
    {
      FT_ifDownlinkAbort(PtrRWChannel);
    }
    /* Disable the storage in the mass memory */
    if(PtrRWChannel->StoreEnable == FT_STR_ALL)
    {
      FT_ifStoreAbort(PtrRWChannel);
    }
    
    /* Find the failed column reading the Hard Error Register  */
    FD_piDrammaRdRPBUSReg(MemModule,FD_HARD_ERROR_REG,&hwErr);
    /* retrieve the bits from 13 to 15                         */
    failed_col_num = ((hwErr & 0x0000E000)>>13);
    failed_col_bit = ( 0x01 << failed_col_num);

    /* If spare column is available switch                     */
    if (pM->Column[FT_SPARE_COL] == FT_COLUMN_OFF)
    {
    	/* Switch off failed column */
       FD_piDrammaWrWPBUSReg (MemModule, FD_REINIT,0);
       /* Program Dramma SCRUBBING and REFRESH register      */
       FD_piDrammaWrWPBUSReg (MemModule, FD_SCRUBBER_REFRESH, FD_SCRABBER_REFRESH_VALUE);
       /* Get columns enable                                 */
       FD_piDrammaRdRPBUSReg (MemModule, FD_PENDING_INT, &pendingVal);
       colEnable  = FD_COLUMN_ENABLE(pendingVal);
       configRegVal = FD_CONFIG_REG_27_11_B | ((MemModule&0x07) << 22) | colEnable;
       /* Fail column OFF                                    */
       configRegVal &=~failed_col_bit;
       FD_piDrammaWrWPBUSReg (MemModule,FD_CONFIGURATION,configRegVal);
       /* Wait 1 ms before to put ON the spare column        */
       OS_piTaskSuspend (1);
       /* Spare column ON                                    */
       configRegVal |= FD_CONFIG_REG_COL_11;
       FD_piDrammaWrWPBUSReg (MemModule, FD_CONFIGURATION,configRegVal);
       /* Program Latchup Retry counter 3 ms                 */ 
       FD_piDrammaWrWPBUSReg (MemModule, FD_LATCH_UP_RETRY, FD_LATCHUP_RETRY_VAL); 
       /* Wait 2 ms                                          */
       OS_piTaskSuspend (2);
       /* Update columns status    */
       pM->Column[failed_col_num] = FT_COLUMN_FAIL;
       pM->Column[FT_SPARE_COL] = FT_COLUMN_ON;
       /* Start up memory module operations              */
       FD_piDrammaWrWPBUSReg (MemModule, FD_INITREG, FD_INITREG_START);
       /* Wait 2 ms,  to complete start operations       */
       OS_piTaskSuspend (2);
       /* Unmask all memory module interrupts            */
       FD_piDrammaWrWPBUSReg (MemModule, FD_INTMSK, FD_MM_INT_ABIL_ALL);
    }
    else /* spare column is not available                      */
    {
       /* Memory Module is marked fail                        */
       pM->State = FT_STATE_MOD_FAIL;
    }
}




/*****************************************************************************/
/* @Function: FT_ifColumnLatchUp                                             */
/* @Purpose :                                                                */
/*  The function menages the colummns latchup recovery procedure.            */
/*  The actions executed in the procedure are the following:                 */
/*      -  If the flag parameter is TRUE the Memory Module device is carried */
/*         in idle state.                                                    */
/*      -  Activation of the columns in latchup. Each column in latchup is   */
/*         forced OFF, the Latchup Retry Counter register is writed, and     */
/*         then the column is forced ON again. Before to continue in the     */
/*         latchup procedure esecution the task wait 2 ms.                   */
/*      -  Reading of the pending interrupt register to check if there are   */
/*         again columns in latchup condition:                               */
/*         Zero column error the Memory Module is OK.                        */
/*         One column error the Memory Module is not considered in fail      */
/*         because the spare column could be used.                           */
/*         More than one column in error the Memory Module is in fail.       */
/* If column latchup procedure is ended correctly and the flag parameter is  */
/* TRUE, the INITREG register is programmed to carry out from idle state the */
/* Memory Module.                                                            */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  MemModule            IN      Memory Module (FT_MEMORY_MODULE type)       */
/*  ConfigVal            IN      Value to write in Configuration register    */
/*  Columns              IN      Columns in error                            */
/*  ActivationColFlag    IN      Flag to carry in or to carry out from the   */
/*                               idle state the Memory Module device         */
/*  ColumnsError        OUT      Returned column status                      */
/*                               (bit 0 to 10 columns, bit to 1 specifies    */
/*                                the column error)                          */
/*  PendingVal          OUT      Returned Pending Interrupt register         */
/* @@                                                                        */
/*****************************************************************************/

status_code FT_ifColumnLatchUp (unsigned int  MemModule,
                                unsigned int  ConfigVal,
                                unsigned int  Columns,
                                unsigned int  ActivationColFlag,
                                unsigned int* ColumnsError,
                                unsigned int* PendingVal)
{
status_code  status;
unsigned int configRegVal;
unsigned int pendingVal;
unsigned int maskCol;
unsigned int colError;
unsigned int colLatchUp;
unsigned int i;

    configRegVal =ConfigVal;
    /* If column at the end of procedure must be          */
    /* activated first set REINIT and SCRUBB register     */
    if (ActivationColFlag)
    {
        /* Program Dramma REINT register                  */
        FD_piDrammaWrWPBUSReg(MemModule,FD_REINIT,0);
        /* Program Dramma SCRUBBING and REFRESH register  */
        FD_piDrammaWrWPBUSReg(MemModule,FD_SCRUBBER_REFRESH,FD_SCRABBER_REFRESH_VALUE);
        /* Clear all memory module interrupts             */
        FD_piDrammaWrWPBUSReg(MemModule,FD_INTCLR,FD_MM_INT_ALL);
        /* Mask all memory module interrupts              */
        FD_piDrammaWrWPBUSReg(MemModule,FD_INTMSK,FD_MM_INT_ALL);
    }
    /* Try to activate the columns in Latch Up            */ 
    for (i=0,maskCol =FD_CONFIG_REG_COL_01; i<FD_MAX_COLUMN_ENABLE; i++,maskCol <<=1)
    {
        if (Columns & maskCol)
        {
            /* Column OFF                                 */
            configRegVal &=~maskCol;
            FD_piDrammaWrWPBUSReg(MemModule,FD_CONFIGURATION,configRegVal);
	          /* Wait 1 ms before switch on the column      */
      	    OS_piTaskSuspend (1);
            /* Column ON                                  */
            configRegVal |=maskCol;
            FD_piDrammaWrWPBUSReg(MemModule,FD_CONFIGURATION,configRegVal);
            /* Write LATCHUP RETRAY register              */ 
            FD_piDrammaWrWPBUSReg(MemModule,FD_CONFIGURATION,FD_LATCHUP_RETRY_VAL);
            /* Wait 6 ms before to activate the next column */
            OS_piTaskSuspend (2);
        }
    }
    /* Read again Pending Interrupt register              */              
    FD_piDrammaRdRPBUSReg (MemModule,FD_PENDING_INT,&pendingVal);
    *PendingVal =pendingVal;
    /* Take only the Latch Up bits                        */
    pendingVal  =FD_MM_LTATCHUP_BIT(pendingVal);
    /* Check interrupt Latch Up monitor bits              */
    if (pendingVal)
    {
        /* Clear all memory module interrupts             */
        FD_piDrammaWrWPBUSReg(MemModule,FD_INTCLR,FD_MM_INT_ALL);
        /* Check if there are again columns in error      */
        maskCol    =FD_CONFIG_REG_COL_01;
        colError   =0;
      	colLatchUp =0;
        for (i=0; i<FD_MAX_COLUMN_ENABLE; i++,maskCol <<=1)
        {
            if (pendingVal & maskCol)
            {
                colError++;
            		colLatchUp =maskCol;
            }
        }
        /* Verify how many columns are again in error     */
        if (colError <= FD_MAX_COLUMN_ERROR)
        {
            /* There is 1 column in error                 */
            /* Return SUCCESSFUL because could be used    */
            /* the spare column for recover the module    */
            status =SUCCESSFUL;
                
        }
        else
        {
            /* There is more than 1 column in error       */
            /* The Columns are switched OFF               */
            status =UNSATISFIED;
        }
        /* Set columns in error                           */
        *ColumnsError = colLatchUp;  //pendingVal;

    }
    else/*===================== Columns are OK ===========================*/
    {
        /* Check if column must be activated                              */
        if (ActivationColFlag)
        {
            /* Start memory module operation programming INITREG register */
            FD_piDrammaWrWPBUSReg(MemModule,FD_INITREG,FD_INITREG_START);
            /* Wait 2 ms,time in order to complete the start operations   */
            OS_piTaskSuspend (2);
            /* Unmask all memory module interrupts                        */
            FD_piDrammaWrWPBUSReg(MemModule,FD_INTMSK,FD_MM_INT_ABIL_ALL);
        }
        *ColumnsError =0;
        status =SUCCESSFUL;
    }
    return (status);    

}



/*****************************************************************************/
/* @Function: FT_ifColumnSwitch                                              */
/* @Purpose :                                                                */
/*  The function performs the switch between the column specified in the     */
/*  parameter and the spare column.                                          *
/*  The actions executed in the procedure are the following:                 */
/*      -  Masking of all memory module interrupts.                          */
/*      -  Programming of the Dramma REINT register to reset the Memery      */
/*         Module devices without loss the data.                             */
/*      -  Programming of the Dramma SCRUBBING and REFRESH register.         */
/*      -  The specific column is forced OFF.                                */
/*      -  Waiting of 200 us.                                                */
/*      -  The spare column is forced ON.                                    */
/*      -  Programming of the Dramma INITREG to start the Memory Module.     */
/*      -  The task waiting 2 ms to complete the start operations            */
/*      -  Checking of the interrupts Latch Up Monitor bits.                 */
/*      -  If Latch Up condition has occurred the Column Latch Up recovery   */
/*         procedure is invoked.                                             */
/* The function exit with return code SUCCESSFUL if all is OK and            */
/* UNSATISFIED if column switch has not been executed correctly.             */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  MemModule            IN      Memory Module (FT_MEMORY_MODULE type)       */
/*  Column               IN      Column to switch                            */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code FT_ifColumnSwitch (unsigned int MemModule,
                               unsigned int Column)
{
status_code  status;
unsigned int configRegVal;
unsigned int pendingVal;
unsigned int colError;
unsigned int colEnable;
unsigned int i;

    /* Program Dramma REINT register                      */
    FD_piDrammaWrWPBUSReg(MemModule,FD_REINIT,0);
    /* Program Dramma SCRUBBING and REFRESH register      */
    FD_piDrammaWrWPBUSReg(MemModule,FD_SCRUBBER_REFRESH,FD_SCRABBER_REFRESH_VALUE);
    /* Clear all memory module interrupts                 */
    FD_piDrammaWrWPBUSReg(MemModule,FD_INTCLR,FD_MM_INT_ALL);
    /* Mask all memory module interrupts                  */
    FD_piDrammaWrWPBUSReg(MemModule,FD_INTMSK,FD_MM_INT_ALL);
    /* Get columns enable                                 */
    FD_piDrammaRdRPBUSReg (MemModule,FD_PENDING_INT,&pendingVal);
    colEnable  =FD_COLUMN_ENABLE(pendingVal);
    configRegVal =FD_CONFIG_REG_27_11_B | ((MemModule&0x07) << 22) | colEnable;
    /* Fail column OFF                                    */
    configRegVal &=~Column;
    FD_piDrammaWrWPBUSReg(MemModule,FD_CONFIGURATION,configRegVal);
    /* Wait 1 ms before to put ON the spare column        */
    OS_piTaskSuspend (1);
    /* Spare column ON                                    */
    configRegVal |=FD_CONFIG_REG_COL_11;
    FD_piDrammaWrWPBUSReg(MemModule,FD_CONFIGURATION,configRegVal);
    /* Program Latchup Retry counter 3 ms                       */ 
    FD_piDrammaWrWPBUSReg (MemModule,FD_LATCH_UP_RETRY,FD_LATCHUP_RETRY_VAL); 
    /* Wait 2 ms before to check the Latch Up bits        */
    OS_piTaskSuspend (2);
    /* Read Pending Interrupt register                    */              
    FD_piDrammaRdRPBUSReg (MemModule,FD_PENDING_INT,&pendingVal);
    /* Take only the Latch Up bits                        */
    pendingVal  =FD_MM_LTATCHUP_BIT(pendingVal);
    /* Check interrupt Latch Up Monitor bits              */
    if (pendingVal)
    {
        /*====== Column Latch Up recovery procedure ======*/
        /* Clear all memory module interrupts             */
        FD_piDrammaWrWPBUSReg (MemModule,FD_INTCLR,FD_MM_INT_ALL);	
        status =FT_ifColumnLatchUp(MemModule,configRegVal,
                                   FD_CONFIG_REG_COL_11,FALSE,&colError,&pendingVal);
        /* Check if spare column now is OK                */
        if(colError)
        {
            /* Spare column error                         */
            status =UNSATISFIED;
        }
    }
    else 
    { 
        /* Active the column and the Memory Module operations */
        FD_piDrammaWrWPBUSReg(MemModule,FD_INITREG,FD_INITREG_START);
        /* Wait 2 ms before to check the Latch Up interrupt   */
        OS_piTaskSuspend (2);
        /* Unmask all memory module interrupts           */
        FD_piDrammaWrWPBUSReg(MemModule,FD_INTMSK,FD_MM_INT_ABIL_ALL);
        status =SUCCESSFUL;
    }
    
    return (status);

}


                               
/*****************************************************************************/
/* @Function: FT_ifMMSUStatusInit                                            */
/* @Purpose :                                                                */
/*  The function initializes the MMSU status structure with the default      */
/*  value.                                                                   */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  MemModTestDef        IN      Pointer to Memory Module test pattern       */
/*  Mmsu                 OUT     Pointer to MMSU status structure            */
/*                               (FT_MMSU_STATUS type)                       */
/* @@                                                                        */
/*****************************************************************************/
void FT_ifMMSUStatusInit(FT_MMSU_STATUS* Mmsu, void* MemModTestDef)
{
FT_MOD_TEST*  memModTestDef;
unsigned int  i,c;


    /* MMSU Memory Module status initalization  */
    for (i=0; i<FT_MAX_MEM_MOD; i++)
    {
        Mmsu->Module [i].State =FT_STATE_MOD_OK;
        Mmsu->Module [i].Mode  =FT_MODE_MEM_MOD_OFF;
        /* Columns status initalization         */
        for (c=0; c<FT_MAX_COLUMN; c++)
        {
          Mmsu->Module [i].Column[c] =FT_COLUMN_OFF;
        }
        /* Bite status initalization            */
        Mmsu->Module[i].Bite.Abil    =FT_TEST_PATTERN_EN;
        Mmsu->Module[i].Bite.Type    =FT_TEST_PATTERN_FIX;
        Mmsu->Module[i].Bite.Pattern =0x00;
        Mmsu->Module[i].Bite.Result  =FT_TEST_MOD_NOT_PERFORMED;
        Mmsu->Module[i].Bite.HWError =0x00;

        memModTestDef = (FT_MOD_TEST*)MemModTestDef;
        /* Test status initalization            */
        for (c=0; c<FT_MAX_TEST_PATTERN; c++,memModTestDef++)
        {
            Mmsu->Module[i].Test[c]  =*memModTestDef;
        }
    }

}



/*****************************************************************************/
/* @Function: FT_ifMemModuleTestExec                                         */
/* @Purpose :                                                                */
/*  The function menages the Memory Module Test execution. The Test          */
/*  initilizes again the MMSU status information and the File System         */
/*  structures than causes all the stored data to be lost.                   */
/*  No information must be  extracted from the MCMD that is deleted from     */
/*  the partition.                                                           */
/*  The Test execution is started during this step, the following actions    */
/*  are performed:                                                           */
/*      -  Initialization of the MMSU status structure.                      */
/*      -  Searching of the  Memory Module if is in off condition and        */
/*         initializes the test correctly.                                   */
/*      -  Sending a log to the History area to notify the test starting     */
/*         operations.                                                       */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  MemModule            IN      Memory Module identifier.                   */
/*  MemModTestDef        IN      Memory Module test pattern (default value)  */
/*  MMSUStatus           OUT     Pointer to all MMSU status structure        */
/*                               (FT_ALL_MMSU_STATUS type)                   */
/*  TestStatus           OUT     Pointer to test statuts structure           */
/*                               (FT_TEST_MOD_STATUS type)                   */
/* @@                                                                        */
/*****************************************************************************/

void FT_ifMemModuleTestExec (FT_MMSU_STATUS*      MMSUStatus,
                             FT_TEST_MOD_STATUS*  TestStatus,
                             void*                MemModTestDef)
{
status_code     status;
unsigned int    timetagFlag;
unsigned int    module;
unsigned int    testStartFlag;
FT_MEM_MOD*     pM;
    

    if(MMSUStatus->Module[FT_MEM_MOD_1].Mode == FT_MODE_MEM_MOD_ON)
    {
        FT_opMemModuleOFF(FT_MEM_MOD_1);
    }
    if(MMSUStatus->Module[FT_MEM_MOD_2].Mode == FT_MODE_MEM_MOD_ON)
    {
        FT_opMemModuleOFF(FT_MEM_MOD_2);
    }
    /* MMSU status initialization                                      */
    FT_ifMMSUStatusInit(MMSUStatus,MemModTestDef);
    testStartFlag =FALSE;
    
    for (module=FT_MEM_MOD_1; module<FT_MAX_MEM_MOD; module++)
    {
        /* Switch ON Memory Module, if NOT OK is switched OFF          */
        status =FT_opMemModuleON(module);
        if (status==FT_MEM_MOD_SW_ON_OK || status==FT_MEM_MOD_ALREADY_ON)
        {
            /* Try to start the Memory Module test                     */
            status =FT_ifMemModuleTest(module,MMSUStatus,TestStatus);
            if (status==SUCCESSFUL)
            {
                /*=== Module Test is started, exit from the loop ======*/
                testStartFlag =TRUE;
                break;
            }
        }
    }

    if (!testStartFlag)
    {
        /*========================= TEST is ended ==========================*/
        /*= Result of the Memory Module test, Entry 6 Log in History area  =*/
      FT_ifLogHistoryEntry6 (MMSUStatus,__LINE__);    
    }
}



/*****************************************************************************/
/* @Function: FT_ifMemModuleTestInter                                        */
/* @Purpose :                                                                */
/*  The function menages the Scrub Address Overflow interrupt during Memory  */
/*  Module Bite or Test execution. The interrupt goes active evry time the   */
/*  scubber completes a cycle on the whole memory.                           */
/*  If Memory Module is in Bite mode no memory check and no other memory     */
/*  fill are requested therefore will be managed the test end.               */
/*  If Memory Module is in Test mode the whole memory is filled and than     */
/*  checked to verify the presence of the hardware errors.                   */
/*  When the Memory Module test has been completed the following actions are */
/*  performed:                                                               */
/*      -  Checking of the Hardware OR and AND erorr. If such errors is      */
/*         detected the Test or Bite mode is aborted and a message to        */
/*         MMSUManager task is sent to perform the closing operations.       */
/*         A log to History area is sent to notify the cause of the fail.    */
/*      -  In Bite mode no other operation is performed. In Test mode is     */
/*         programmed the next memory test with a new pattern, otherwise if  */
/*         no other test is requested, is sent a message to the MMSUMager to */
/*         manage the closing of the Memory Module test.                     */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  MMSUStatus           OUT     Pointer to all MMSU status structure        */
/*                               (FT_ALL_MMSU_STATUS type)                   */
/*  TestStatus           OUT     Pointer to test statuts structure           */
/*                               (FT_TEST_MOD_STATUS type)                   */
/* @@                                                                        */
/*****************************************************************************/

void FT_ifMemModuleTestInter (FT_MMSU_STATUS*      MMSUStatus,
                              FT_TEST_MOD_STATUS*  TestStatus)
{
FT_MOD_TEST*  pT;
unsigned int  state;  
unsigned int  module; 
unsigned int  testIdx;
unsigned int  mode;
unsigned int  pendingVal;
unsigned int  hwErr;
unsigned int  testEndFlag;
unsigned int  testStartFlag;
unsigned int  i;

    if (TestStatus->State != FT_TEST_NO_RUNNING)
    {
        /* Initialize local variable                    */
        state   =TestStatus->State;  
        module  =TestStatus->Module; 
        testIdx =TestStatus->TestIdx;
        mode    =MMSUStatus->Module[module].Mode;
        testEndFlag =FALSE;
        /* Next state                                   */
        state++;
        TestStatus->State =state;

        if (mode==FT_MODE_MEM_MOD_BITE)
        {
            /* Memmory Module in BITE mode              */ 
            pT =&MMSUStatus->Module[module].Bite;
            testEndFlag =TRUE;
            /* Set testIdx to Max test pattern because  */
            /* in BITE mode no other memory fill need   */
            testIdx     =FT_MAX_TEST_PATTERN;
        }
        else
        {
            /* Memmory Module in TEST mode              */ 
            pT =&MMSUStatus->Module[module].Test[testIdx];
            testEndFlag =(state==FT_TEST_CHECK_PATTERN) ? TRUE : FALSE;
        }
        if (testEndFlag)
        {
            /* Check HW_OR, interrupt                   */
            FD_piDrammaRdRPBUSReg (module,FD_PENDING_INT,&pendingVal);
            pendingVal =FD_MM_INTER_BIT(pendingVal);
            if (pendingVal & FD_MM_INT_HW_OR)
            {
                /* Read Hard Error register             */
                FD_piDrammaRdRPBUSReg(module,FD_HARD_ERROR_REG,&hwErr);
                pT->Result  =FT_TEST_MOD_NOT_OK;
                pT->HWError =hwErr;
                MMSUStatus->Module[module].State =FT_STATE_MOD_FAIL;
                /*================ Module error, stop Test ===================*/
                TestStatus->State =FT_TEST_END;
                if (mode==FT_MODE_MEM_MOD_TEST)
                {
                    /*== Send message to MMSUManager to menage the Test end ==*/
                    FT_ifSndMsgMMSUManager(FT_TEST_MODULE_END,FT_TEST_MOD_NOT_OK);
                }
                /*================ Entry 11 Log in History Area ===============*/
                // LOG_INFN HA_piLogHistoryEntry11(HA_E11_MEMORY_MODULE, HA_E11_MOD_TEST_HW_ERR,module, hwErr);
		/*@LOG Test Module interrupt - hwErr */
		LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,hwErr);
            }
            else
            {
                /* Module test is OK                    */
                pT->Result  =FT_TEST_MOD_OK;
                pT->HWError =0;
                /* Search next pattern                  */
                testStartFlag =FALSE;
                testIdx++;
                while (!testStartFlag && testIdx<FT_MAX_TEST_PATTERN)
                {
                    pT++;  
                    if (pT->Abil==FT_TEST_PATTERN_EN)
                    {
                        /* Start the Memory Module test  */
                        FT_ifStartMemModuleTest(module,pT->Type,pT->Pattern);
                        TestStatus->State =FT_TEST_START;  
                        testStartFlag =TRUE;
                    }
                    else
                    {
                    	testIdx++;
                    }	
                }
                TestStatus->TestIdx =testIdx;
                if (!testStartFlag)
                {
                    /*========== Memmory Module OK, test is finished =========*/
                    TestStatus->State =FT_TEST_END;
                    if (mode==FT_MODE_MEM_MOD_TEST)
                    {
                        /* Send message to MMSUManager to menage the Test end */
                        FT_ifSndMsgMMSUManager(FT_TEST_MODULE_END,FT_TEST_MOD_OK);
                    }
                }
            }
        }
    }
        
}



/*****************************************************************************/
/* @Function: FT_ifMemModuleTest                                             */
/* @Purpose :                                                                */
/*  The function initializes and starts the Memory Module test with a        */
/*  specific pattern.                                                        */
/*  MMSU and Memory Module are specified in the function parameters.         */
/*  The Test Status structure is initialized and a new test pattern is       */
/*  searched into the test pattern table. If new pattern is found the Memory */
/*  Module start procedure is executed. Return code identifier is SUCCESSFUL */
/*  when memory test is started correctly, otherwise is UNSATISFIED.         */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  MemModule            IN      Memory Module (FT_MEMORY_MODULE type)       */
/*  MMSUStatus           OUT     Pointer to all MMSU status structure        */
/*                               (FT_ALL_MMSU_STATUS type)                   */
/*  TestStatus           OUT     Pointer to test statuts structure           */
/*                               (FT_TEST_MOD_STATUS type)                   */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code FT_ifMemModuleTest (unsigned int        MemModule,
                                FT_MMSU_STATUS*     MMSUStatus,
                                FT_TEST_MOD_STATUS* TestStatus)
{
status_code  status;
FT_MEM_MOD*  pM;
FT_MOD_TEST* pT;
unsigned int i;

    /* Set MMSU type                                               */

    /* Initialize the running test structure                       */
    TestStatus->State   =FT_TEST_START;
    TestStatus->Module  =MemModule;
    TestStatus->TestIdx =FT_START_TEST_PATTERN;
    /* Pointer to Module structure                                 */
    pM =&MMSUStatus->Module[MemModule];
    /* Pointer to Test Module structure                            */
    pT =&pM->Test[FT_START_TEST_PATTERN];    
    /* Search first pattern                                        */
    status =UNSATISFIED;
    for (i=FT_START_TEST_PATTERN; i<FT_MAX_TEST_PATTERN; i++,pT++)
    {
        if (pT->Abil==FT_TEST_PATTERN_EN)
        {
            /* Start the Memory Module Test                        */
            FT_ifStartMemModuleTest(MemModule,pT->Type,pT->Pattern);
            pM->Mode =FT_MODE_MEM_MOD_TEST;
            status =SUCCESSFUL;
            break;  /* First pattern found, exit from the loop     */
        }
    }
                        
    return (status);
}



/*****************************************************************************/
/* @Function: FT_ifStartMemModuleTest                                        */
/* @Purpose :                                                                */
/*  The function programs the Dramma registers to perform the test of a      */
/*  specific Memory Module using a defined pattern.                          */
/*  The function parameters specify the MMSU, the Memory Module, the type of */
/*  the test, and the pattern.                                               */
/*  To start the Memory Module test are performed the following actions:     */
/*      -  Clearing of all Memory Module interrupts.                         */ 
/*      -  Masking of the SOFTERROR OVL, HARDERROR AND OR  interrupts        */ 
/*      -  Unmasking of the SCRUB ADDRESS OVL interrupts.                    */
/*      -  Programming of the Dramma REINT register to reset whole device.   */
/*      -  Programming of the Dramma SCRUBBING and REFRESH register.         */
/*      -  Programming of the Dramma INITREG to start memory fill with a FIX */
/*         or VARIABLE pattern depending of the test type parameter.         */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  MemModule            IN      Memory Module (FT_MEMORY_MODULE type)       */
/*  StartType            IN      Type of the memory test                     */
/*                               (FT_TEST_PATTERN_VAR,FT_TEST_PATTERN_FIX)   */
/*  Pattern              IN      Pattern used to fill the memory             */
/* @@                                                                        */
/*****************************************************************************/

void FT_ifStartMemModuleTest(unsigned int  MemModule,
                             unsigned int  StartType,

                             unsigned int  Pattern)
{
unsigned int initReg;

    /* Program Dramma REINT register                          */
    FD_piDrammaWrWPBUSReg(MemModule,FD_REINIT,0);
    /* Program Dramma SCRUBBING and REFRESH register          */
    FD_piDrammaWrWPBUSReg(MemModule,FD_SCRUBBER_REFRESH,FD_SCRABBER_REFRESH_VALUE);
    /* Clear all memory module interrupts                     */
    FD_piDrammaWrWPBUSReg(MemModule,FD_INTCLR,FD_MM_INT_ALL);
    /* Mask SFT_OVL,HW_OR,HW_AND memory module interrupts and */
    /* unmask SA_OVL                                          */
    FD_piDrammaWrWPBUSReg(MemModule,FD_INTMSK,FD_MM_INT_ABIL_SA);
    /* Check test type                                        */
    if (StartType==FT_TEST_PATTERN_VAR)
    {
       /* Start Memory Module filling with a VARIABLE pattern */
       initReg =FD_INITREG_PATTERN_VAR;
       FD_piDrammaWrWPBUSReg(MemModule,FD_INITREG,initReg);
    }
    else
    {
       /* Start Memory Module filling with a FIX pattern      */
       initReg =FD_INITREG_PATTERN_FIX | Pattern;
       FD_piDrammaWrWPBUSReg(MemModule,FD_INITREG,initReg);
    }
}



/*****************************************************************************/
/* @Function: FT_ifTestModuleEnd                                             */
/* @Purpose :                                                                */
/*  The function menages the Memory Module test end condition, and the       */
/*  starting of the next Memeory Module test.                                */
/*  The actions performed are the following:                                 */
/*      -  The MMSU Test Running Status structure is reseted.                */
/*      -  The Memory Module is forced to OFF condition.                     */
/*      -  Searching of the next Memory Module to test and calling the       */
/*         function to perform the test starting.                            */
/*      -  The MMSU is forced to OFF condition if all Memory Module have     */
/*         executed the test procedure.                                      */
/*      -  If both MMSU local and remote have completed the Memory Module.   */
/*         test is sent a log to History area with the results of the tests. */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  MMSUStatus           OUT     Pointer to all MMSU status structure        */
/*                               (FT_ALL_MMSU_STATUS type)                   */
/*  TestStatus           OUT     Pointer to test statuts structure           */
/*                               (FT_TEST_MOD_STATUS type)                   */
/*  TestStatus           OUT     Pointer to test statuts structure           */
/*                               (FT_TEST_MOD_STATUS type)                   */
/* @@                                                                        */
/*****************************************************************************/

void FT_ifTestModuleEnd (unsigned int         TestResult,
                         FT_MMSU_STATUS*      MMSUStatus,
                         FT_TEST_MOD_STATUS*  TestStatus)
{
status_code   status;
FT_MEM_MOD*   pM;
unsigned int  module;
unsigned int  endTestFlag;
unsigned int  testStartFlag;

    module =TestStatus->Module;

    /* Reset of the MMSU Test Running Status structure   */
    TestStatus->State   =FT_TEST_NO_RUNNING;
    TestStatus->Module  =0xffffffff; /* No Module index  */
    TestStatus->TestIdx =0xffffffff; /* No Pattern index */

    /* Memory Module Test is ended, switch OFF the Module                   */
    status =FT_piMemModuleOFF(module);
    /* Test the next Memory Module                                          */
    module++;
    testStartFlag =FALSE;
    endTestFlag   =FALSE;
    while (!testStartFlag && !endTestFlag && (TestResult!=FT_TEST_MOD_ABORT))
    {
        /* Check if all MMSU Memory Module are tested                       */
        if (module<FT_MAX_MEM_MOD)
        {
            /* Switch ON Memory Module, if NOT OK is switched OFF           */
            status =FT_opMemModuleON(module);
            if (status==FT_MEM_MOD_SW_ON_OK)
            {
                /* Try to start the Memory Module test                      */
                status =FT_ifMemModuleTest(module,MMSUStatus,TestStatus);
                if (status==SUCCESSFUL)
                {
                    /*==== Module Test is started, exit from the loop ======*/
                    testStartFlag =TRUE;
                }
            }
            if (!testStartFlag)
            {
                module++;
            }
        }
        else
        {
            endTestFlag =TRUE;
        }
    }

    if (endTestFlag || (TestResult==FT_TEST_MOD_ABORT))
    {
        /*========================= TEST is ended ==========================*/
        /* Sending a log to the History area to notify the Pdht Test result */
        FT_ifLogHistoryEntry6 (MMSUStatus,__LINE__);

    }

}

/*****************************************************************************/
/* @Function: FT_ifLogHistoryEntry6                                          */
/* @Purpose :                                                                */
/*  The function compiles a message (MsgTask structure) whose content        */
/*  (Info field) is foramtted in according to the layout defined by the      */
/*  Entry Type 6.  The message is sent into the mailbox of the HistoryArea   */
/*  object.                                                                  */
/*  The Entry Type 6 defines the PDHT test results. The details are obtained */
/*  by calling a function that compiles a report word in according to the    */
/*  Entry Type 6 format.                                                     */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  MMSUStatus           IN      Pointer to all MMSU status structure        */
/*                               (FT_ALL_MMSU_STATUS type)                   */
/* @@                                                                        */
/*****************************************************************************/

void FT_ifLogHistoryEntry6 (FT_MMSU_STATUS*  MMSUStatus,unsigned int line)
{
MsgTsk       sndMsg;
TI_TIME      obtime;
unsigned int testReport;

    /* Get OBT to time tag the Log       */
#warning do we want OBT in s or in ms ? if ms, russian must be warned ?
    TI_piGetTimeInfo_ms(&obtime);
    /* Get the PDHT current state        */

    
    /* Get Test report                   */
    FT_ifGetReportTest(MMSUStatus,&testReport);



    
    /* Compile the Entry Type 6 fields           
    *((unsigned short* )&sndMsg.Info[0]) =HA_HEADER_E6 | HA_E6_TEST_MCMD_FLAG;
    *((unsigned short* )&sndMsg.Info[2]) =(obtime >>16);
    *((unsigned short* )&sndMsg.Info[4]) =(obtime & 0xffff);
    *((unsigned short* )&sndMsg.Info[6]) =(testReport & 0xffff);
    *((unsigned short* )&sndMsg.Info[8]) = 0x0000;
    sndMsg.Code   = HA_TRACEVENT;
    sndMsg.LlInfo = HA_SIZEW_E0;
    */

    /* Send message to the Histrory area */
    // HA_piSndMsgHistoryArea(&sndMsg);
    /*@LOG LOG History Entry 6 - testreport */
    LU_INFN_LOG(LU_CRITICAL|LU_HA|LU_NORMAL_TRACE,LU_MASK(__FILEID__),__FILEID__,line,testReport);
}



/*****************************************************************************/
/* @Function: FT_ifGetReportTest                                             */
/* @Purpose :                                                                */
/*  The function formats the MMSUs (Local and Remote) test results in        */
/*  according to the bits structure defined in the Entry Type 6 layout.      */
/*  The test informations are obtained from the content of the MMSU status   */
/*  structure.                                                               */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  MMSUStatus           IN      Pointer to all MMSU status structure        */
/*                               (FT_ALL_MMSU_STATUS type)                   */
/*  Report               OUT     Returned test report                        */
/* @@                                                                        */
/*****************************************************************************/

void  FT_ifGetReportTest(FT_MMSU_STATUS* MMSUStatus, unsigned int* Report)
{
FT_MEM_MOD*   pM;
unsigned int  mask;
unsigned int  report;
unsigned int  i;

     /* Report structure :                                               */
     /*  15  14  13  12  11  10  9   8   7   6   5   4   3   2   1   0   */
     /*                                                          M2  M1  */

    /*=========== Get MMSU Local test result =========*/
    pM =&MMSUStatus->Module[0];
    for (i=0,mask =1,report =0; i<FT_MAX_MEM_MOD; i++,pM++,mask <<=1)
    {
        if (pM->State != FT_STATE_MOD_OK)
        {
            report |=mask;
        }
    }
    
    *Report = report;
    
}

/*****************************************************************************/
/* @Function: FT_ifGetModeDetails                                            */
/* @Purpose :                                                                */
/*  The function formats the current Mission Modes status in according to    */
/*  to the bits structure defined in the Entry Type 0 layout.                */
/*  The Mission Modes informations are obtained from the content of the Open */
/*  Channel structure. From each open channel are extracted the current      */
/*  information about the status of the active operational mode.             */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  ChOpen               IN      Pointer to the channels structure           */
/*                               (FT_CHANNELS_OPEN type)                     */
/*  Report               OUT     Returned test report                        */
/* @@                                                                        */
/*****************************************************************************/

void FT_ifGetModeDetails (unsigned int*     ModeReport)
{
unsigned int      modeRep;

    modeRep =0;
    *ModeReport =modeRep;
}

/*****************************************************************************/
/* @Function: FT_ifMCMDDownLinkExec                                          */
/* @Purpose :                                                                */
/*  The function menages the Downlink MCMD execution by opening the RWChannel*/
/*  in downlink mode, switching onthe TAM IF and starting the StartPlayback  */
/*  trigger Timer                                                            */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  PtrMcmd              IN      Pointer to MCMD header                      */
/*                               (MA_HEADER_MCMD type)                       */
/*  status_code          OUT     Return code                                 */
/*  PtrRWChannel         IN      Pointer to the RWchannel manage structure   */
/* @@                                                                        */
/*****************************************************************************/

status_code FT_ifMCMDDownLinkExec(MA_HEADER_MCMD* PtrMcmd,
                              FT_RW_CH* PtrRWChannel)
{
status_code status = HA_E2_MCMD_OK;
 UINT16*       pMcmdInfo;
 UINT32        timetagFlag;
 UINT32        fileId;
 UINT32        rawFlag;
 UINT32        dlSectors;
 UINT32        tamId;
 
 UINT32        totalSize;
 UINT32        sectors;
 FS_FILE_DESCR fileInfo;
 MsgTsk        Msg;
 SM_ACQMODE    acqMode;
 FS_EXITCODE   imageStat;
 BOOL          newImage;
 /* word to send to INFN */
 UINT16        word_06;
 UINT16        word_07;
 UINT16        word_08;
 TI_TIME       WaitForStartDownlink;
 TI_TIME       DownlinkStartTime;
 TI_TIME       DownlinkIntervalTime;
 TI_TIME       CurrentMoscowTime;

  /* Extract parameters and delete MCMD from partition  */

  pMcmdInfo   =(UINT16* )PtrMcmd->PtrMCMD;
  // Bit 0
  fileId =(UINT32)((*(pMcmdInfo+OFFSET_HEADER)) & 0x0001);
  // Bit 1-2
  tamId =(UINT32)((*(pMcmdInfo+OFFSET_HEADER)) & 0x0006) >> 1;
  // Bit 3
  rawFlag =(UINT32)((*(pMcmdInfo+OFFSET_HEADER)) & 0x0008) >> 3;
  // Bit 4-15
  dlSectors =(UINT32)((*(pMcmdInfo+OFFSET_HEADER)) & 0xfff0) >> 4;
  word_06 = *(pMcmdInfo + OFFSET_HEADER + 1);
  word_07 = *(pMcmdInfo + OFFSET_HEADER + 2);
  word_08 = *(pMcmdInfo + OFFSET_HEADER + 3);

  /* get the 6th bit for the main/spare selector: */
  // Changed since TM in Rome: main_spare = (word_08 & 0x0020) >> 5;
  FT_main_spare = (word_07 & 0x0020) >> 5;

  /* Delete MCMD from partition                         */
  timetagFlag =(*(pMcmdInfo+1)&TIMETAG_MASK) ? TIMETAG_MCMD : IMMEDIATE_MCMD;
  MA_piDelBufferMCMD(PtrMcmd->PtrMCMD,timetagFlag);

 /* here call INFN provided interface for copy word_0x */

 /* Check that the active memory module is ON */
 if(PtrRWChannel->PtrModuleStatus->Mode != FT_MODE_MEM_MOD_ON)
  {
    status = HA_E2_MOD_NOT_AVAILABLE;
  }
 
 /* Check that the read channel is not already in use */
  if(PtrRWChannel->ReadMode != FT_CLOSED)
    {
      status = HA_E2_DL_RUNNING;
    }
  
  if(status == SUCCESSFUL)
    {
      PtrRWChannel->ReadSectors = 0;
      /* Init the playback automa status */
      PtrRWChannel->PlayBackStatus = FT_READY;

      /*
       * Possibile Ottimizzazione spostare il cambio di stato e 
       * il setting di PtrRWChannel->ReadMod dopo il timer!!
       */
#warning "Possibile Ottimizzazione spostare il cambio di stato e il setting di PtrRWChannel->ReadMod dopo il timer"
      
      /* Stop the acquisition and the SRAM page storage */

#if 0      
#warning "e' necessario mettere in SM_IDLE lo stato?????"
      acqMode = PM_pi_GetAcqMode();
      PM_pi_SetAcqMode(SM_IDLE);
      FT_ifDisableStore(PtrRWChannel, TRUE);
#endif
      
      if(rawFlag == TRUE)
	{
	  /* Prepare a sector chain that starts from the sector number 0 and */
	  /* has the selected number of sectors                              */
	  // FS_piMakeFileImage(0, (dlSectors * FT_SECTSIZE) / FT_SAMPLESIZE, &sectors, TRUE);
	  /* Lock the read channel in raw downlink mode */
	  PtrRWChannel->ReadMode = FT_BITEDNLK;
	}
      else
	{
	  /* Prepare a sector chain that covers all the sectors used by the  */
	  /* selected file and the HK file */
	  
	  /* we have deleted FILE2*/
	  // PtrRWChannel->FileId = (fileId == FT_FILE1) ? FS_FILE1 : FS_FILE2;
	  PtrRWChannel->FileId = FS_FILE1;
	  
	  /* Lock the read channel in downlink mode */
	  PtrRWChannel->ReadMode = FT_DOWNLINK;
	}


      /* Switch on the selected TAM I/F */
      
      /* FROM BRANCH_TM_SAMARA*/
      // TM_piSendTC      (TM_VRL_MAIN_OFF,1);
      // TM_piSendTC      (TM_VRL_SPARE_OFF,1);      
      HK_SendTC      (TM_VRL_OFF,1);
      //      HK_SendTC      (TM_VRL_SPARE_OFF,1);
      
      OS_piTaskSuspend (PRH_VAR_TM_VRL_SUSPEND_HCL);
      // old.. to remove 
      //    HK_SendTC      (TM_VRL_STOP,1);
      //    OS_piTaskSuspend (PRH_VAR_TM_VRL_SUSPEND_HCL);
 
    if(FT_main_spare == FT_VRL_MAIN)
      HK_SendTC      (TM_VRL_MAIN_ON_START,1);
    else
      HK_SendTC      (TM_VRL_SPARE_ON_START,1);
    
    
    PtrRWChannel->TamId=tamId;
    /* Start the timer that will trigger the palyback start as soon as the */
    /* selected TAM I/F has completed the warm up                          */
    
    /*
      Set Timer to Downlink Start  
    */
    
    status = TI_piGetCurrentMoscowTime_s(&CurrentMoscowTime);  
    
    if (status != SUCCESSFUL)
      {
	/*@LOG Downlink: error getting current moscow time - status */
	LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
	status = HA_E2_INTERNAL_ERR;
	FT_ifStopDownLink(PtrRWChannel);
	// oppure FT_ifDownLinkClose(PtrRWChannel); ??
      }
    else {
    
      status = MH_GetDownlinkInfo(&DownlinkStartTime,&DownlinkIntervalTime);
    
      if (status != SUCCESSFUL)
	{
	  /*@LOG Downlink: error getting downlink info  - status */
	  LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
	  status =HA_E2_INTERNAL_ERR;
	  FT_ifStopDownLink(PtrRWChannel);
	  // oppure FT_ifDownLinkClose(PtrRWChannel); ??
	}
      else
	{
	  
	  PtrRWChannel->DownlinkStartTime = DownlinkStartTime;
	  PtrRWChannel->DownlinkIntervalTime = DownlinkIntervalTime;
	  
	  WaitForStartDownlink = 0;
	  
	  if (DownlinkStartTime > CurrentMoscowTime){
	    WaitForStartDownlink = DownlinkStartTime - CurrentMoscowTime; 

	  }

	  if(WaitForStartDownlink < FT_TAM_WARMUP)
	    WaitForStartDownlink = FT_TAM_WARMUP;

	  //WaitForStartDownlink=20;

	  status = OS_piStartTimer(FT_TIM, TI_SECOND_TO_TICK(WaitForStartDownlink),
				   FT_ifStartDownLink_CallBack, (void*)PtrRWChannel);
	  /*@LOG Downlink: wait for start downlink*/
	  LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,WaitForStartDownlink);
	  /*@LOG Downlink: duration of downlink */
	  LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,DownlinkIntervalTime);

	  if (status != SUCCESSFUL)
	    {
	      // LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_FS,HA_E10_TIMER_ERR,status);
	      /*@LOG Timer not started correctly - status */
	      LU_INFN_LOG(LU_FATAL|LU_HA ,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
	      status =HA_E2_INTERNAL_ERR;
	      FT_ifStopDownLink(PtrRWChannel);
	      // oppure FT_ifDownLinkClose(PtrRWChannel); ??
	    }
	  /* Re-enable the store channel */
	  /* and the perviously interrupted acquisition activity */
#if 0
	  FT_ifEnableStore(PtrRWChannel);
	  PM_pi_SetAcqMode(acqMode);
#endif
	}
    }
  }
  if (status != SUCCESSFUL)
    {
      /*@LOG Downlink Error */      
      LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
      /*============= Entry 2 Log in History Area ==========*/
    }
  return (status);
}

/*****************************************************************************/
/* @Function: FT_ifMCMDAbordExec                                             */
/* @Purpose :                                                                */
/*  The function menages the Abort MCMD execution by calling the proper      */
/*  function to abort the Downlink, Mass Memory storage or Test operation.   */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  PtrMcmd              IN      Pointer to MCMD header                      */
/*                               (MA_HEADER_MCMD type)                       */
/*  status_code          OUT     Return code                                 */
/*  PtrRWChannel         IN      Pointer to the RWchannel manage structure   */
/* @@                                                                        */
/*****************************************************************************/
status_code FT_ifMCMDAbordExec(MA_HEADER_MCMD* PtrMcmd,
                               FT_RW_CH* PtrRWChannel,
                               FT_TEST_MOD_STATUS* PtrTestModuleStatus)
{
status_code status = HA_E2_MCMD_OK;
UINT16* pMcmdInfo;
UINT32  timetagFlag;
UINT32  abortType;

  /* Extract parameters and delete MCMD from partition  */
  pMcmdInfo   =(UINT16* )PtrMcmd->PtrMCMD;
  // Abort Type parameter
  abortType =(UINT32)((*(pMcmdInfo+OFFSET_HEADER)) & 0x0007);

  /* Delete MCMD from partition                         */
  timetagFlag =(*(pMcmdInfo+1)&TIMETAG_MASK) ? TIMETAG_MCMD : IMMEDIATE_MCMD;
  MA_piDelBufferMCMD(PtrMcmd->PtrMCMD,timetagFlag);

  if(abortType & FT_ABORT_DLK)
  {
    if(PtrRWChannel->ReadMode == FT_CLOSED)
    {
      /* Downlink not running       */
      /*============= Entry 2 Log in History Area ==========*/
      // LOG_INFN HA_piLogHistoryEntry2(PtrMcmd->Type,HA_E2_INVALID_DL_ABORT);
      LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,HA_E2_INVALID_DL_ABORT);      
      status = HA_E2_INVALID_ABORT;
    }
    else
    {
      /* Downlink running, abort it */
      FT_ifDownlinkAbort(PtrRWChannel);
    }
  }

  if(abortType & FT_ABORT_S2M)
  {
      /* SRAM to MMSU running, abort it */
      FT_ifStoreAbort(PtrRWChannel);
  }

  if(abortType & FT_ABORT_TST)
  {
    if(PtrTestModuleStatus->State == FT_TEST_NO_RUNNING)
    {
      /* Test not running       */
      /*============= Entry 2 Log in History Area ==========*/
      // LOG_INFN HA_piLogHistoryEntry2(PtrMcmd->Type,HA_E2_INVALID_TEST_ABORT);
      LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,HA_E2_INVALID_TEST_ABORT);      
      status = HA_E2_INVALID_ABORT;
    }
    else
    {
      /* Test running, abort it */
      PtrTestModuleStatus->State = FT_TEST_NO_RUNNING;
      FT_ifSndMsgMMSUManager(FT_TEST_MODULE_END,FT_TEST_MOD_ABORT);
    }
  }
  /*============= Entry 2 Log in History Area ==========*/
  // LOG_INFN HA_piLogHistoryEntry2 (PtrMcmd->Type,status);
  LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);      
}



/*****************************************************************************/
/* @Function: FT_ifStartDownLink                                             */
/* @Purpose :                                                                */
/*  This function is used to start the Playback operation.                   */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  PtrRWChannel         IN      Pointer to the RWchannel manage structure   */
/*  TimerId              IN      Timer identification                        */
/* @@                                                                        */
/*****************************************************************************/

void FT_ifStartDownLink(FT_RW_CH* PtrRWChannel)
{
  unsigned int intLevel;
  FS_SECT_DESCR sectorInfo;
  status_code status;
  TI_TIME   DownlinkTime;

  SM_ACQMODE    acqMode;
  
  /* Check if the read channel is locked in any kind of downlink mode */
  if(PtrRWChannel->ReadMode == FT_DOWNLINK ||
     PtrRWChannel->ReadMode == FT_BITEDNLK)
    {

#if 1
#warning "e' necessario mettere in SM_IDLE lo stato?????"
      acqMode = PM_pi_GetAcqMode();
      PM_pi_SetAcqMode(SM_IDLE);
      FT_ifDisableStore(PtrRWChannel, TRUE);
#endif

      /*========= Entry 0 Log in History Area ==========*/
      // LOG_INFN HA_piLogHistoryEntry0(HA_E0_STARTING,HA_E0_DOWN_LINK,HA_E0_DL_BIT);
      /*@LOG Start downlink */
      LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,HA_E0_DL_BIT);      
      /* Enable the playback related interrupt */
      OS_piInterDisable(&intLevel);
      SD_piClearInt(SD_RPB_EOT);
      SD_piUnMaskInt(SD_RPB_EOT);
      OS_piInterEnable(intLevel);

      /* Program the DRAMMA and WPBUS with the info about the first two sectors */
      /* and start the data transfer                                            */
      FS_piGetCurrentSector(&sectorInfo);
      FD_piDrammaWrWPBUSReg(PtrRWChannel->ActiveModule, FD_RADDR1_WPBUS, sectorInfo.SectAddr);

      // per consentire il download di settori da 1024*1015 byte, abbiamo aggiunto la seguente istruzione e cambiato quella successiva

      FD_piSetBlockLength(FT_SECTSIZE / FT_SAMPLESIZE);
      
      // Start Timer di finestra temporale downlink.    
      
      DownlinkTime = PtrRWChannel->DownlinkIntervalTime;
      
      status = OS_piStartTimer_INFN(DNLK_TIM, TI_SECOND_TO_TICK(DownlinkTime),
				    FT_ifStopDownLink_CallBack, (void*)PtrRWChannel);
      /*@LOG Downlink: StartTimer_INFN - status */
      LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
      if (status != SUCCESSFUL)
	{
	  /* Timer not started correctly           */
	  // LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_FS,HA_E10_TIMER_ERR,status);
	  /*@LOG Downlink - status */
	  LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);      
	  status =HA_E2_INTERNAL_ERR;
	  FT_ifStopDownLink(PtrRWChannel);
	  // oppure FT_ifDownLinkClose(PtrRWChannel); ??
	}
      else
	{
	  /*============= Entry 2 Log in History Area ==========*/
	  //  HA_piLogHistoryEntry2 (PtrMcmd->Type,status);
	  FD_piStartTransferFromMemory(PtrRWChannel->ActiveModule, TRUE); 

	  OS_piTaskSuspend (PRH_VAR_TM_VRL_SUSPEND_BEFORE_START);
	  // FROM BRANCH_TM_SAMARA
	  if(FT_main_spare == FT_VRL_MAIN)
	    HK_SendTC      (TM_VRL_MAIN_ON_START,1);
	  else 
	    HK_SendTC      (TM_VRL_SPARE_ON_START,1);
	  //	  HK_SendTC 
	  //	  TM_piSendTC      (TM_VRL_START,1);
	  OS_piTaskSuspend (PRH_VAR_TM_VRL_SUSPEND_HCL);

          // FD_piStartTransferFromMemory(PtrRWChannel->ActiveModule, FALSE);
	}

      /*
	This 3-line comment had indroduced from zulianello@laben in his visit in Roma, 28.07.2003
	in order to fix the "End of 1-MB gap problem"

	FS_piGetNextSector(&sectorInfo);
	FD_piDrammaWrWPBUSReg(PtrRWChannel->ActiveModule, FD_RADDR1_WPBUS, sectorInfo.SectAddr);
	FD_piStartTransferFromMemory(PtrRWChannel->ActiveModule, FALSE);
      */

      PtrRWChannel->PlayBackStatus = FT_RUN;      

#if 1
	  FT_ifEnableStore(PtrRWChannel);
	  PM_pi_SetAcqMode(acqMode);
#endif

    }
}


/*****************************************************************************/
/* @Function: FT_ifDownLinkClose                                             */
/* @Purpose :                                                                */
/*  This function is used to close the Downlink operation and RWChannel      */
/*  via the MMSU Manager                                                     */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  PtrRWChannel         IN      Pointer to the RWchannel manage structure   */
/* @@                                                                        */
/*****************************************************************************/

rtems_timer_service_routine FT_ifStopDownLink_CallBack(rtems_id timer_id,void *PtrRWChannel)
{
  MsgTsk SndMsg;
  status_code s;
  SndMsg.Code = FT_STOP_DOWNLINK;
  s=FT_opSndMsgMMSUManager(&SndMsg);
}

rtems_timer_service_routine FT_ifStartDownLink_CallBack(rtems_id timer_id,void *PtrRWChannel)
{
  MsgTsk SndMsg;
  status_code s;
  SndMsg.Code = FT_START_DOWNLINK;
  s=FT_opSndMsgMMSUManager(&SndMsg);
}

/*****************************************************************************/
/* @Function: FT_ifDownLinkClose                                             */
/* @Purpose :                                                                */
/*  This function is used to close the Downlink operation and RWChannel      */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  PtrRWChannel         IN      Pointer to the RWchannel manage structure   */
/* @@                                                                        */
/*****************************************************************************/

void FT_ifStopDownLink(FT_RW_CH* PtrRWChannel)
{
  unsigned int intLevel;
  status_code status; 
  // Disable ReadEOT
  OS_piInterDisable(&intLevel);
  SD_piClearInt(SD_RPB_EOT);
  SD_piMaskInt(SD_RPB_EOT);
  OS_piInterEnable(intLevel);
  



 // SET START to 0       : START HLC 4

  // FROM BRANCH_TM_SAMARA

  //  if(FT_main_spare == FT_VRL_MAIN)
  HK_SendTC      (TM_VRL_OFF,1);
  // else 
  //      HK_SendTC      (TM_VRL_SPARE_OFF,1);

  /*

  HK_SendTC        (TM_VRL_STOP, 0x1);
  OS_piTaskSuspend   (PRH_VAR_TM_VRL_SUSPEND_HCL);
  
  HK_SendTC        (TM_VRL_OFF, 0x1);
  
  */
  OS_piTaskSuspend   (PRH_VAR_TM_VRL_SUSPEND_HCL);


  // Reset DMA forse non necessario!!!
  FD_piAbortTransfer(FD_ABT_READ);

  OS_piCancelTimer_INFN(DNLK_TIM);
  
  status = FS_piUpdateSectorPointer();

    /* Close the read channel */
  PtrRWChannel->ReadMode = FT_CLOSED;
   /* Update the store channel status enabling again the storage */
  /* into mass memory                                            */
  FT_ifEnableStore(PtrRWChannel);
  /*@LOG Stop Download - status */
  LU_INFN_LOG(LU_NORMAL_TRACE|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
  PM_SendCommand(PM_INFN_END_OF_DOWNLINK);
}

/*****************************************************************************/
/* @Function: FT_ifDownLinkClose                                             */
/* @Purpose :                                                                */
/*  This function is used to close the Downlink operation and RWChannel      */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  PtrRWChannel         IN      Pointer to the RWchannel manage structure   */
/* @@                                                                        */
/*****************************************************************************/

void FT_ifDownLinkClose(FT_RW_CH* PtrRWChannel)
{
  unsigned int intLevel;
  
  if(PtrRWChannel->ReadMode == FT_DOWNLINK)
  {
    /* If a playback operation of a regular file was ended then          */
    if(PtrRWChannel->PlayBackStatus == FT_END) {
      /* Reset the files that has just been downloaded */
      FS_piResetFile(PtrRWChannel->FileId);
      FS_piResetFile(FS_HK);
      /*========= Entry 0 Log in History Area ==========*/
      // LOG_INFN HA_piLogHistoryEntry0(HA_E0_EXITING,HA_E0_DOWN_LINK,0);
      /*@LOG DownLinkClose: reset file */
      LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,0);      
    }
  }
  /* End of a raw downlink */
  if(PtrRWChannel->ReadMode == FT_BITEDNLK)
  {
    if(PtrRWChannel->PlayBackStatus == FT_END) {
      /*========= Entry 0 Log in History Area ==========*/
      // LOG_INFN HA_piLogHistoryEntry0(HA_E0_EXITING,HA_E0_DOWN_LINK,0);
      /*@LOG DownLinkClose: BITE in progress */
      LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,0);      
    }
  }
  /* Close the read channel */
  PtrRWChannel->ReadMode = FT_CLOSED;
  /* Update the store channel status enabling again the storage */
  /* into mass memory                                            */
  FT_ifEnableStore(PtrRWChannel);
}

/*****************************************************************************/
/* @Function: FT_ifDownlinkAbort                                             */
/* @Purpose :                                                                */
/*  This function is used to close the Downlink operation and RWChannel      */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  PtrRWChannel         IN      Pointer to the RWchannel manage structure   */
/* @@                                                                        */
/*****************************************************************************/

void FT_ifDownlinkAbort(FT_RW_CH* PtrRWChannel)
{
status_code status;
unsigned int intLevel;

  /* Stop the trigger timer for the downlink  */
  OS_piCancelTimer(FT_TIM);
  /* Disable all the store related interrupts */
  OS_piInterDisable(&intLevel);
  SD_piMaskInt(SD_RPB_EOT);
  OS_piInterEnable(intLevel);
  /* If a playback is running then  */
  if(PtrRWChannel->PlayBackStatus != FT_READY &&
     PtrRWChannel->PlayBackStatus != FT_END)
  {
    /* Abort the RPBUS transfer     */
    FD_piAbortTransfer(FD_ABT_READ);
  }
  /* Close the downlink operation */
  FT_ifDownLinkClose(PtrRWChannel);
}

/*****************************************************************************/
/* @Function: FT_ifRWChannelInit                                             */
/* @Purpose :                                                                */
/*  This function initializes the RWChannel structure used to supervise the  */
/*  data flow to or from the memory module                                   */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  status_code          OUT     Return code                                 */
/*  PtrRWChannel         IN      Pointer to the RWchannel manage structure   */
/*  PtrModInfo           IN      Pointer to the active module info structure */
/*  Module               IN      Active Module                               */
/* @@                                                                        */
/*****************************************************************************/

status_code FT_ifRWChannelInit(FT_RW_CH* PtrRWChannel,
                               FT_MEMORY_MODULE Module,
                               FT_MEM_MOD* PtrModInfo)
{
status_code status = SUCCESSFUL;
unsigned int intLevel;

  /* program the WPBUS/RPBUS wait state counters */
  FD_piSetWPBUSWaitState(FT_WPBUS_WCS);
  FD_piSetRPBUSWaitState(FT_RPBUS_WSC);
  // By default the Active module is the Primary module
  PtrRWChannel->ActiveModule = Module;
  PtrRWChannel->PtrModuleStatus = PtrModInfo;
  PtrRWChannel->ReadMode = FT_CLOSED;
  PtrRWChannel->ReadSectors = 0;
  PtrRWChannel->PlayBackStatus = FT_END;
  PtrRWChannel->FileId = FS_MAXID;
  PtrRWChannel->SaveInProgress = FALSE;
  PtrRWChannel->CurrentPageId = SM_SKETCHBOARD;
  PtrRWChannel->StoreEnable = FT_STR_NONE;
  OS_piInterDisable(&intLevel);
  /* disable any read/store related interrupts */
  SD_piMaskInt(SD_WPB_EOT | SD_RPB_EOT);
  OS_piInterEnable(intLevel);
  /* release the semaphore on save queue*/
  //  OS_piResourceRelease ( FT_RES );
  //  console_outbyte_polled( 0, 'R' );
  //  console_outbyte_polled( 0, '\n' );	 
  return (status);
}

/*****************************************************************************/
/* @Function: FT_ifDisableStore                                              */
/* @Purpose :                                                                */
/*  This function is used to stop the SRAM page storage operations.          */
/*  The current store operation is stopped, the save queue reset and no more */
/*  save request are accepted.                                               */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  PtrRWChannel         IN      Pointer to the RWchannel manage structure   */
/*  AllStr               IN      Flag to force the reinit of store automa    */
/* @@                                                                        */
/*****************************************************************************/

void FT_ifDisableStore(FT_RW_CH* PtrRWChannel, BOOL AllStr)
{
unsigned int intLevel;
FT_SAVEREQUEST saveReq;
UINT32 reqSize;

  if(AllStr) {
    /* Disable the store chanel */
    PtrRWChannel->StoreEnable = FT_STR_NONE;
    /* If a store operation was in progress then */
    if(PtrRWChannel->SaveInProgress == TRUE) {
      /* Abort the WPBUS transfer */
      FD_piAbortTransfer(FD_ABT_WRITE);
    }
        /* Notify the SRAMPageManager that any save request */
    /* about the skatchboard has been cancelled         */
    OS_piInterDisable(&intLevel);
    PM_piPageWasSaved(FS_HK);
    OS_piInterEnable(intLevel);
    /* release the semaphore on save queue*/
    // OS_piResourceRelease ( FT_RES );
    // console_outbyte_polled( 0, 'R' );
    // console_outbyte_polled( 0, '\n' );	 
  }
  else
  {
    PtrRWChannel->StoreEnable = FT_STR_CMD;
  }
}

/*****************************************************************************/
/* @Function: FT_ifEnableStore                                               */
/* @Purpose :                                                                */
/*  This function is used to start the SRAM page storage operations.         */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  PtrRWChannel         IN      Pointer to the RWchannel manage structure   */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code FT_ifEnableStore(FT_RW_CH* PtrRWChannel)
{
status_code status = FT_STR_DONE;
unsigned int intLevel;
FT_SAVEREQUEST saveReq;
UINT32 reqSize;

  /* If the store channel was closed */
  if(PtrRWChannel->StoreEnable == FT_STR_NONE)
  {
    /* Init the store flag */
    PtrRWChannel->SaveInProgress = FALSE;
    PtrRWChannel->CurrentPageId = SM_SKETCHBOARD;
  }
  /* If the read channel is closed and the current memory module */
  /* is up and running                                           */
  if(PtrRWChannel->ReadMode == FT_CLOSED &&
     PtrRWChannel->PtrModuleStatus->State == FT_STATE_MOD_OK &&
     PtrRWChannel->PtrModuleStatus->Mode == FT_MODE_MEM_MOD_ON) {
    /* Enable the storage both in the mass memory and towards    */
    /* the CMD I/F                                               */
    PtrRWChannel->StoreEnable = FT_STR_ALL;
    OS_piInterDisable(&intLevel);
    /* enable eny store related interrupts */
    SD_piUnMaskInt(SD_WPB_EOT);
    OS_piInterEnable(intLevel);
    /* release the semaphore on save queue*/
    // OS_piResourceRelease ( FT_RES );
    //    console_outbyte_polled( 0, 'R' );
    //    console_outbyte_polled( 0, '\n' );	 
  }
  else
  {
    /* Enable only the data transfer towards the CMD I/F         */
    PtrRWChannel->StoreEnable = FT_STR_CMD;
  }
}

/*****************************************************************************/
/* @Function: FT_ifBiteTORecovery                                            */
/* @Purpose :                                                                */
/*  This function handles the timeout event during a BITE operation          */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  PtrRWChannel         IN      Pointer to the RWchannel manage structure   */
/*  TimerId              IN      Timer identification                        */
/* @@                                                                        */
/*****************************************************************************/

void FT_ifBiteTORecovery(unsigned int TimerId, FT_RW_CH* PtrRWChannel)
{
  /* If the BITE operation dosen't end then close it and mark the module bad */
  FD_piDrammaWrWPBUSReg(PtrRWChannel->ActiveModule,FD_INTMSK,FD_MM_INT_DISABIL);
  PtrRWChannel->PtrModuleStatus->State = FT_STATE_MOD_FAIL;
  PtrRWChannel->PtrModuleStatus->Mode = FT_MODE_MEM_MOD_ON;
}

/*****************************************************************************/
/* @Function: FT_ifStoreAbort                                                */
/* @Purpose :                                                                */
/*  This function is used to close the Downlink operation and RWChannel      */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  PtrRWChannel         IN      Pointer to the RWchannel manage structure   */
/* @@                                                                        */
/*****************************************************************************/

void FT_ifStoreAbort(FT_RW_CH* PtrRWChannel)
{
SM_ACQMODE acqMode;

    /* Reinit the data acquisition and SRAM page store operations  */
    acqMode = PM_pi_GetAcqMode();
    
    /* HW reset of PIF */
    SD_piPIFReset();
    /* 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);
    
    
    PM_pi_SetAcqMode(SM_IDLE);
    FT_ifDisableStore(PtrRWChannel, TRUE);
    FT_ifEnableStore(PtrRWChannel);
    PM_pi_SetAcqMode(acqMode);
}


