/****************************************************************************
/*  F i l e   D a t a                                                        
/*                                                                           
/*  Module       :  QualitySystem                                                
/*  C.I. No.     :                                                           
/*  $Revision: 1.1.1.1 $
/*  $Date: 2006/04/25 09:00:21 $
/*  Belonging to :                                                           
/*               :                                                           
/*  $RCSfile: QS_DiagSupervisor_op.c,v $
/*  Program Type :                                                           
/*  Sub-modules  :                                                           
/*                                                                           
/****************************************************************************
/*  S W   D e v e l o p m e n t   E n v i r o n m e n t                      
/*                                                                           
/*  Host system  :                                                           
/*  SW Compiler  :                                                           
/*  $Author: kusanagi $
/*               :                                                           
/****************************************************************************
/*  U p d a t i n g                                                          
/*                                                                           
/*  $Log: QS_DiagSupervisor_op.c,v $
/*  Revision 1.1.1.1  2006/04/25 09:00:21  kusanagi
/*  These program extract in an XML format the info contained into the ROOT files generated by YODA from the PAMELA data. To visualize the XML files in a more human readable format a collection of XSL files are given in the Data subfolder.
/*
/*  Revision 1.11  2005/03/20 18:30:33  sebastiani
/*  WATCHDOG_RESET enabled in correct and definitive way
/*
/*  Revision 1.10  2005/02/21 08:58:29  sebastiani
/*  all log comments completed
/*
/*  Revision 1.9  2004/09/22 09:56:21  sebastiani
/*  added watchdog
/*
/*  Revision 1.8  2004/09/17 15:01:00  faber
/*  LU_INFN_LOG flags fixing
/*
/*  Revision 1.7  2004/09/08 10:39:12  faber
/*  *** empty log message ***
/*
/*  Revision 1.6  2004/07/27 08:36:16  sebastiani
/*  add cpu idle info
/*
/*  Revision 1.5  2004/07/26 09:27:46  faber
/*  *** empty log message ***
/*
/*  Revision 1.4  2004/05/10 12:59:17  faber
/*  __FILEID__ right value fixed: many .c files had the wrong value!
/*
/*  Revision 1.3  2004/03/09 19:08:15  faber
/*  Dont make the DiagSupervisior task ready in simulator mode
/*
/*  Revision 1.2  2003/10/21 16:09:12  alfarano
/*  LU_LOG_INFN replacement for all remaining original log functions
/*
/*  Revision 1.1.1.1  2003/08/04 09:40:21  sebastiani
/*  Imported sources laben rel. 19.06.2003 integrated with pam2
/*
/*  Revision 1.3  2002/05/09 08:16:35  zulia
/*  *  acceptance release
/*
/*                                                                           
/*****************************************************************************/


/*============================= Include File ================================*/
  
#include <src/QualitySystem/DiagSupervisor/QS_DiagSupervisor_op.h>
#include <src/HKManager/HistoryArea/HA_HistoryArea_p.h>
#include <src/BasicSW/InterruptManager/IM_InterruptManager_p.h>

#include <src/INFN/LU_SourceFileID_INFN.h>
#define __FILEID__ _QS_DiagSupervisor_op__c
#include <src/INFN/PRH_ParamHandler_INFN.h>
#include <src/INFN/LU_LogUtility_INFN.h>
#include <src/INFN/CM_Common_INFN.h>
#include <src/INFN/PRH_ParamHandler_INFN_auto.h>
LU_DECL_MASK();

#ifdef DEBUG
#define QS_CPU_USAGE
#else
#undef  QS_CPU_USAGE
#endif


#ifdef QS_CPU_USAGE
static unsigned long int QS_Scrubbing_Counter=0;
static unsigned long int QS_Calibrated_Scrubbing_Counter=17647901;
static TI_TIME QS_Calibrated_Scrubbing_Delay=65535;
static rtems_interval QS_tsb_start=0;
#endif

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


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

/*= D i a g S u p e  r v i s o r   O P E R A T I O N A L  F U N C T I O N S =*/

status_code QS_NormalPriority() {
  unsigned int OldPriority;
  return OS_piTaskPriority( QS_TASK,DIAGSUPERVISOR_PRIORITY,&OldPriority);
}



/*****************************************************************************/
/* @Function: QS_opInit                                                      */
/* @Purpose :                                                                */
/*  The function initializes the Diagnostic Supervisor object.               */
/*  The OS directives are called to set priority and to ready the            */
/*  DiagSupervisor task.                                                     */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* status_code          OUT     Return code                                  */
/* @@                                                                        */
/*****************************************************************************/

status_code QS_opInit(void)
{
  status_code  status;        
 
  status  =SUCCESSFUL;
  
    /* Task initialization                        */

#ifndef SIMULATOR
  if (OS_piTaskReady(QS_TASK,QS_tkDiagSupervisor) != SUCCESSFUL)
    {
      /*@LOG Task is not correctly started LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_QS,HA_E10_TSK_READY_ERR,status); */
      LU_INFN_LOG(LU_FATAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
      status  =UNSATISFIED;
    }
#endif

  if ((status=QS_NormalPriority()) != SUCCESSFUL)
    {
      /*@LOG Task priority is not correctly updated  LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_QS,HA_E10_TSK_PRIORITY_ERR,status);     */
      LU_INFN_LOG(LU_FATAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status);
      status  =UNSATISFIED;
    }
  
  return (status);
  
}


status_code QS_opUsageStart() {
#ifdef QS_CPU_USAGE
  rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT,&QS_tsb_start);
  QS_Scrubbing_Counter=0;
#endif
  return CM_RC_SUCCESSFUL;
}

status_code QS_opUsageStop(UINT16 *usage) {
#ifdef QS_CPU_USAGE
  rtems_interval tsb_stop;
  rtems_interval t_interval;
  unsigned long int lusage,vscrubbing_max,vscrubbing_now;
  rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT,&tsb_stop);
  /*
    formula is:

           (QS_Calibrated_Scrubbing_Counter/QS_Calibrated_Scrubbing_Delay)
     u=   ---------------------------------------------------------------- * 1000
                   (QS_Scrubbing_Counter / (tsb_stop-QS_tsb_start)) 
   */
  t_interval = tsb_stop-QS_tsb_start;
  vscrubbing_max = QS_Calibrated_Scrubbing_Counter / (QS_Calibrated_Scrubbing_Delay == 0 ? 1 : QS_Calibrated_Scrubbing_Delay);
  vscrubbing_now = QS_Scrubbing_Counter / ( (t_interval == 0) ? 1 : t_interval);
  lusage = (vscrubbing_now * 1000) / (vscrubbing_max == 0 ? 1 : vscrubbing_max);
  *usage = (UINT16)lusage;
#endif
  return CM_RC_SUCCESSFUL;
}

status_code QS_opCounterCalibration(TI_TIME tics) {
#ifdef QS_CPU_USAGE
  status_code s;
  rtems_id taskid;
  rtems_task_priority my_old_priority,unused;
  s=rtems_task_ident(RTEMS_SELF,RTEMS_SEARCH_ALL_NODES,&taskid);
  if(s)
    return s;
  s=rtems_task_set_priority(taskid,1,&my_old_priority);
  QS_Scrubbing_Counter=0;
  if(s)
    return s;
  s=OS_piTaskPriority(QS_TASK,2,&unused);
  if(s)
    return s;
  OS_piTaskSuspend(tics);
  QS_Calibrated_Scrubbing_Counter=QS_Scrubbing_Counter;
  QS_Calibrated_Scrubbing_Delay=tics;
  QS_Scrubbing_Counter=0;
  s=QS_NormalPriority();
  if(s)
    return s;
  s=rtems_task_set_priority(taskid,my_old_priority,&unused);
  if(s)
    return s;
#endif  
  return CM_RC_SUCCESSFUL;
}

/*****************************************************************************/
/* @Function: QS_tkDiagSupervisor                                            */
/* @Purpose :                                                                */
/*  The function is the task handler of the DiagSupervisor object.           */
/*  The DiagSupervisor task activity is to manage the read and write         */
/*  of the whole memory RAM in a cyclical mode.                              */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* status_code          OUT     Return code                                  */
/* @@                                                                        */
/*****************************************************************************/

// static BOOL watchdog_able=0;

task QS_tkDiagSupervisor (task_argument unused)
{
unsigned int  level;
unsigned int* pRam;
unsigned int  value;
unsigned int  i;
    while( FOREVER ) 
    {
        /* Read and write all memoryRAM                 */
        for (i=0,pRam =(unsigned int*)QS_RAM_START_ADDR; i<QS_RAM_SIZE; i++,pRam++)
        {
            level    =sparc_disable_interrupts();
            /* Read a word from the memory RAM location */
            value =*pRam;
            /* Wite a word into the memory RAM location */
            *pRam =value;
            /* Reset Watchdog Timer register            */
	    //	    if(watchdog_able)
	    WATCHDOG_RESET;
            sparc_enable_interrupts(level); 
#ifdef QS_CPU_USAGE
#warning CPU USAGE MONITORING FEATURE ON
	    QS_Scrubbing_Counter++;
#endif
        }
    }
}

