/****************************************************************************
/*  F i l e   D a t a                                                        
/*                                                                           
/*  Module       :  HK_Manager_INFN                                                
/*  C.I. No.     :                                                           
/*  $Revision: 1.1.1.1 $
/*  $Date: 2006/04/25 09:00:20 $
/*  $Revision: 1.1.1.1 $
/*  $Date: 2006/04/25 09:00:20 $
/*  Belonging to :                                                           
/*               :                                                           
/*  $RCSfile: HK_Manager_INFN.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                                                          
/*                                                                           
/*
/*                                                                           
/*****************************************************************************/


/*============================= Include File ================================*/
  
#include <src/INFN/LU_SourceFileID_INFN.h>
#define __FILEID__ _HK_Manager_INFN__c
#include <src/INFN/PRH_ParamHandler_INFN.h>
#include <src/INFN/LU_LogUtility_INFN.h>
#include <src/INFN/PRH_ParamHandler_INFN_auto.h>
LU_DECL_MASK();

#include <src/TM_TCManager/TMTCManager/TM_TMTCManager_op.h>
#include <src/INFN/HK_Manager_INFN.h>
#include <src/INFN/HB_HKBuffer_INFN.h>
#include <src/INFN/KHB_Driver_INFN.h>
#include <src/INFN/GS_Gas_INFN.h>
#include <src/BasicSW/TimingInfo/TI_TimingInfo_p.h>

static TI_TIME HK_LastTCHLCall = 0; 
static int HK_KHBBusyFlag = FALSE;


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

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

/*       P a y l o a d s   O P E R A T I O N A L  F U N C T I O N S          */

/*****************************************************************************/
/* @Function: HK_InitHKManager                                               */
/* @Purpose :                                                                */
/*  Initialialization function of the HK component.                          */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code HK_InitHKManager (void)
  {
    status_code       status;
    void            * p;
    unsigned short  * pR;
    unsigned int      OldPriority;
    
    // Task initialization

    if ((status=OS_piTaskReady_INFN(HK_INFN_TASK,HK_tkHKManager)) != SUCCESSFUL)
      {
	/*@LOG Task is not correctly started - status */
	LU_INFN_LOG (LU_CRITICAL, LU_MASK(__FILEID__), __FILEID__, __LINE__, status);    
        
	status = UNSATISFIED;
      }

    if ( (status=OS_piTaskPriority_INFN(HK_INFN_TASK,  HK_MANAGER_PRIORITY,  &OldPriority)) != SUCCESSFUL)
      {
        /*@LOG Task priority is not correctly updated - status*/
	LU_INFN_LOG (LU_CRITICAL, LU_MASK(__FILEID__), __FILEID__, __LINE__, status);    

        status = UNSATISFIED;
      }
    
    return (status);
  }

/*****************************************************************************/
/* @Function: HK_SndMsgHKManager                                             */
/* @Purpose :                                                                */
/*  The function  invokes the directive of the OS to send a message to the   */
/*  HKManager mailbox.                                                       */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/*  SndMsg               IN      Message buffer that contains task operation */
/*  status_code          OUT     Return code                                 */
/* @@                                                                        */
/*****************************************************************************/

status_code HK_SndMsgHKManager (MsgTsk* SndMsg)
  {
    status_code   status;

    // Send message to HK_SndMsgHKManager task mailbox

    status = OS_piMsgQueueSend_INFN(HK_INFN_MAILBOX,  (void *) SndMsg,  sizeof(MsgTsk));
    switch(status) { 
    case RTEMS_TOO_MANY:
      /*@LOG Too many messages in task queue - status */
      LU_INFN_LOG (LU_DEBUG_TRACE, LU_MASK(__FILEID__), __FILEID__, __LINE__, status);    
      break;
    case RTEMS_SUCCESSFUL:
      break;
    default:
      /*@LOG unrecognized error in sendin message - status */
      LU_INFN_LOG (LU_CRITICAL, LU_MASK(__FILEID__), __FILEID__, __LINE__, status);    
      break;
    }
    return (status);
  }

#define HK_EndOfOp(status_ptr,stat,taskid) do { \
     *(status_code*)(status_ptr) = (stat); \
     rtems_event_send((taskid),OS_EVENT_HK_DONE); \
} while (0)


status_code HK_RestoreSavedCommands() 
{	
  UINT32 task_id,status_ptr;
  UINT32 size;
  MsgTsk Msg;
  status_code s;
  BYTE *p;
  BYTE tmp;
  while(OS_piMsgQueueReceive_INFN(SAVED_HK_MAILBOX,&Msg,&size,RTEMS_NO_WAIT,0) == CM_RC_SUCCESSFUL) 	
    {
      s = OS_piMsgQueueSend_INFN(HK_INFN_MAILBOX,&Msg,sizeof(Msg));
      if (s != CM_RC_SUCCESSFUL)
	{
	  p=Msg.Info;
	  CM_READ_BE_UINT32(p,task_id,tmp);
	  CM_READ_BE_UINT32(p,status_ptr,tmp);
	  HK_EndOfOp(status_ptr,s,task_id);
	}
    }
  return CM_RC_SUCCESSFUL;
}


#define _HK_FILTER_TM(tm_id,dest,source) do { \
  switch(PRH_ARR_TM_FILTER_OPERATION[tm_id]) { \
  case 1: \
    dest[tm_id]=PRH_ARR_TM_FILTER_VALUE[tm_id]; \
    break; \
  case 2: \
    dest[tm_id]=source[tm_id] | PRH_ARR_TM_FILTER_VALUE[tm_id]; \
    break; \
  case 3: \
    dest[tm_id]=source[tm_id] & PRH_ARR_TM_FILTER_VALUE[tm_id]; \
    break; \
  default: \
    dest[tm_id]=source[tm_id]; \
    break; \
  } } while(0)



void HK_FILTER_TM(TM_TELEMETRY tm_id,UINT32 *value) 
{ 
  switch(PRH_ARR_TM_FILTER_OPERATION[tm_id]) { 
  case 1: 
    *value=PRH_ARR_TM_FILTER_VALUE[tm_id]; 
    break; 
  case 2: 
    *value |= PRH_ARR_TM_FILTER_VALUE[tm_id]; 
    break; 
  case 3: 
    *value &= PRH_ARR_TM_FILTER_VALUE[tm_id]; 
    break; 
  default: 
    // let the value untouched 
    break; 
  }
}


/*****************************************************************************/
/* @Function: HK_tkHKManager                                                 */
/* @Purpose :                                                                */
/*  The function is the task handler of the HK_tkHKManager object.           */
/*  When a message is received into task mailbox it wakes up.                */
/*  The information contained in the message (MsgTsk structure) define       */
/*  parameters (Info field), and the operation type that the task performs   */
/*  (Code field).                                                            */
/*  The HK_tkHKManager task activity is to activate the cyclic telemetry     */
/*   acquisitin.                                                             */
/*                                                                           */
/* @@                                                                        */
/* @Parameter Name      @Mode   @Description                                 */
/* @@                                                                        */
/*****************************************************************************/


task HK_tkHKManager (task_argument unused)
{
  status_code       status;
  MsgTsk            RxMsg;
  unsigned int      MsgSize;
  UINT32 taskid,status_ptr,code,value,value_ptr,all_values_ptr;
  BYTE *p,tmp;
  BOOL HK_KHB_lock = FALSE;
  BYTE counter,link;
  UINT32 combuf;
  UINT32 saved_outbuf;
  UINT32 saved_status_ptr;
  UINT32 saved_taskid;
  UINT32 saved_expected;
  UINT32 timeout = 0;	      
  UINT32 saved_retry_counter;
  TM_TELEMETRY tm;


  while (FOREVER) 
    {
      
      RxMsg.Code = NULL_MSG_TM;
      
      // Wait for a message to become available
      
      if ((status = OS_piMsgQueueReceive_INFN(HK_INFN_MAILBOX,  (void *) &RxMsg,   &MsgSize,  WAIT,   NO_TIMEOUT)) == SUCCESSFUL)
	{
	  p = RxMsg.Info;
	  CM_READ_BE_UINT32(p,taskid,tmp);
	  CM_READ_BE_UINT32(p,status_ptr,tmp);
	  	  
	  switch (RxMsg.Code)
	    {
	    case HK_SAVE_TMTC_VALUES :
	      status = HB_StoreTMTC();
	      HK_EndOfOp(status_ptr,status,taskid);  
	      break;
	      
	    case HK_CYCLIC_ACQUISITION :
	      if (HK_KHB_lock) {
		status = OS_piMsgQueueSend_INFN(SAVED_HK_MAILBOX,(void*)&RxMsg,sizeof(RxMsg));
		if(status != CM_RC_SUCCESSFUL)
		  HK_EndOfOp(status_ptr,status,taskid);
	      } else {
		UINT32 *tm_value;
		CM_READ_BE_UINT32(p,all_values_ptr,tmp);
		TM_DoCyclicAcq();
		TM_piGetAllTMValue((void*)all_values_ptr);
		tm_value=(UINT32*)all_values_ptr;
		for(tm=TM_MIN_TELEMETRY;tm<TM_MAX_TELEMETRY;tm++,tm_value++) 
		  HK_FILTER_TM(tm,tm_value);
		
		
		HK_EndOfOp(status_ptr,status,taskid);
	      }
	      break;
	      
	    case HK_SEND_TC:
	      {
		TI_TIME diff; 

		CM_READ_BE_UINT32(p,code,tmp);
		CM_READ_BE_UINT32(p,value,tmp);
		
		TI_piGetTimeInfo_ms(&diff);
		
		diff-= HK_LastTCHLCall;

		if (diff < PRH_VAR_PWR_WAIT_BEFORE_SENDTC)		
		  OS_piTaskSuspend(PRH_VAR_PWR_WAIT_BEFORE_SENDTC-diff);
		
		status = TM_piSendTC(code,value); 
		TI_piGetTimeInfo_ms(&HK_LastTCHLCall);
		HK_EndOfOp(status_ptr,status,taskid);  
	      }
	      break;
	      
	    case HK_GET_TM_VALUE:
	      
	      CM_READ_BE_UINT32(p,code,tmp);
	      CM_READ_BE_UINT32(p,value_ptr,tmp);
	      status = TM_piGetTMValue(code,TM_CURRENT_VAL,(UINT32*)value_ptr);
	      
	      HK_FILTER_TM(code,((UINT32*)value_ptr));

	      HK_EndOfOp(status_ptr,status,taskid);
	      break;

	    case HK_KHB_FE_COM_BLOCK:
	      {
		MsgTsk HK_MsgToFe;				
		BYTE tmp;
				
		if (HK_KHB_lock)
		    status = OS_piMsgQueueSend_INFN(SAVED_HK_MAILBOX,(void*)&RxMsg,sizeof(RxMsg));
		else
		  {
		    saved_taskid=taskid;
		    saved_status_ptr=status_ptr;
		    CM_READ_BE_UINT8(p,counter);
		    CM_READ_BE_UINT8(p,saved_expected);
		    CM_READ_BE_UINT8(p,link);
		    CM_READ_BE_UINT32(p,saved_outbuf,tmp);
		    CM_READ_BE_UINT32(p,combuf,tmp);
		    CM_READ_BE_UINT32(p,saved_retry_counter,tmp);
		    
		    status = KHB_SendFECommand(link,counter,saved_expected,(UINT16*)combuf);		
		    
		    if(status==CM_RC_SUCCESSFUL) 
		      {
			// if (!saved_expected) {HK_EndOfOp(status_ptr,status,taskid); break;}
			HK_KHB_lock = TRUE;
			OS_piStartTimer_INFN(HK_POLL_KHB_TIM,KHB_WAIT_TIMEBUF,HK_SendPoll_CallBack,NULL);
		      }
		    else
		      HK_EndOfOp(status_ptr,status,taskid);
		      
		  }
	      }
	      break;
	      
	    case HK_POLL_KHB:
	      {
		UINT16 stw=0xffff;

		if(HK_KHB_lock==TRUE) {
		  // read status word from kayser

		  status = KHB_ReadStatusRegister(&stw);                                                     

		  if(PRH_VAR_VERBOSE_DEBUG)
		    /*@LOG KHB Status Register during polling - khb_status_register */
		    LU_INFN_LOG (LU_DEBUG_TRACE, LU_MASK(__FILEID__), __FILEID__, __LINE__, stw);		    
		
		  if (status == CM_RC_SUCCESSFUL)
		    {
		      if ((stw & KHB_STATUS_MASK) == KHB_STATUS_VALUE)
			{
#ifndef SIMULATOR
			  counter = (stw >> 8) & 0xf;
#else		      
			  counter = 0;
#endif
			  if(saved_retry_counter)
			    saved_retry_counter--;
		      
			  // buffer filled 
			  if (counter >=saved_expected)
			    {
			      if (counter > saved_expected)
				/*@LOG paranoia check during polling: counter > expected - counter */
				LU_INFN_LOG (LU_CRITICAL, LU_MASK(__FILEID__), __FILEID__, __LINE__, counter);
			      if(saved_expected)
				status = KHB_ReadBuffer(saved_expected,(UINT16*)saved_outbuf);
			      HK_KHB_lock = FALSE;
			    }
			  else
			    {
			      // buffer not yet complete  
			      if (saved_retry_counter) 
				OS_piStartTimer_INFN(HK_POLL_KHB_TIM,KHB_WAIT_TIMEBUF,HK_SendPoll_CallBack,NULL);
			      else
				{
				  UINT16 * tmpptr = (UINT16*)saved_outbuf;
				  *tmpptr = counter;
				  tmpptr++;
				  if(counter)
				    status = KHB_ReadBuffer(counter,tmpptr);
				  status = CM_RC_TIMEOUT;
				  HK_KHB_lock = FALSE;
				  /*@LOG KHB polling: saved_retry_counter == 0 - khb_status_register */
				  LU_INFN_LOG (LU_DEBUG_TRACE, LU_MASK(__FILEID__), __FILEID__, __LINE__, stw);

				}
			    }
			}
		      else
			{
			  status = CM_RC_KHB_ERROR;
			  HK_KHB_lock = FALSE;
			  *(UINT16*)saved_outbuf = stw;
			  /*@LOG KHB Status Register : (stw & KHB_STATUS_MASK) != KHB_STATUS_VALUE) during polling - khb_status_register */
			  LU_INFN_LOG (LU_DEBUG_TRACE, LU_MASK(__FILEID__), __FILEID__, __LINE__, stw);		    
			  
			}
		    }
		  else  // bad read register
		    HK_KHB_lock = FALSE;
		  
		  // HK_KHB_lock is here well set to the new value . In case its FALSE, then also che 'status' value is
		  // set to the right status value to notify to the caller task
		  
		  if (!HK_KHB_lock)
		    {
		      HK_RestoreSavedCommands();
		      HK_EndOfOp(saved_status_ptr,status,saved_taskid);
		    }
		  // if HK_KHB_lock is TRUE here, KHB is still locked, and 'status' should be zero. do nothing
		}
		else
		  /*@LOG KHB polling: the board software status is unlocked */
		  LU_INFN_LOG (LU_DEBUG_TRACE, LU_MASK(__FILEID__), __FILEID__, __LINE__,0);
	      }
	      break;
	    case  HK_KHB_INIT_BOARD:
	      {
		if(HK_KHB_lock) 
		  {
		    OS_piCancelTimer_INFN (HK_POLL_KHB_TIM);
		    HK_RestoreSavedCommands();
		    status=CM_RC_HK_CMD_CANCELLED;
		    HK_EndOfOp(saved_status_ptr,status,saved_taskid);
		    HK_KHB_lock = FALSE;
		  }
		status=KHB_InitBoard();
		HK_EndOfOp(status_ptr,status,taskid);
	      }
	      break;
	    case HK_KHB_HARD_RESET: 
	      {
		if(HK_KHB_lock) 
		  {
		    OS_piCancelTimer_INFN (HK_POLL_KHB_TIM);
		    HK_RestoreSavedCommands();
		    status=CM_RC_HK_CMD_CANCELLED;
		    HK_EndOfOp(saved_status_ptr,status,saved_taskid);
		    HK_KHB_lock = FALSE;
		  }
		status=KHB_HWReset();
		HK_EndOfOp(status_ptr,status,taskid);
	      }
	      break;
	    case HK_KHB_UPDATE_MASK_REG:
	      {
		UINT16 mask;
		BYTE action;
		/* are we sure that we can avoid this lock? */
		if (HK_KHB_lock) {
		  /* postpone request */
		  status = OS_piMsgQueueSend_INFN(SAVED_HK_MAILBOX,(void*)&RxMsg,sizeof(RxMsg));
		  if(status != CM_RC_SUCCESSFUL)
		    HK_EndOfOp(status_ptr,status,taskid);
		} else {
		  CM_READ_BE_UINT16(p,mask,tmp);
		  CM_READ_BE_UINT8(p,action);
		  status = KHB_UpdateMaskRegister(mask,action);
		  HK_EndOfOp(status_ptr,status,taskid);  
		}

	      }
	      break;	      
	    case HK_KHB_READ_ALARM_REG:
	      {
		UINT32 mask_p;
		/* are we sure that we can avoid this lock? */
		if (HK_KHB_lock) {
		  /* postpone request */
		  status = OS_piMsgQueueSend_INFN(SAVED_HK_MAILBOX,(void*)&RxMsg,sizeof(RxMsg));
		  if(status != CM_RC_SUCCESSFUL)
		    HK_EndOfOp(status_ptr,status,taskid);
		} else {
		  CM_READ_BE_UINT32(p,mask_p,tmp);
		  status = KHB_ReadAlarmRegister((UINT32*)mask_p);
		  HK_EndOfOp(status_ptr,status,taskid);  
		}
	      }
	      break;
	    case HK_KHB_READ_STATUS_REG:
	      CM_READ_BE_UINT32(p,value_ptr,tmp);
	      status = KHB_ReadStatusRegister((UINT16*)value_ptr);
	      HK_EndOfOp(status_ptr,status,taskid);  
	      break;
	    case HK_KHB_SEND_128_TRIGGER:
	      status = KHB_SendTrigger();
	      HK_EndOfOp(status_ptr,status,taskid);  
	      break;
	    case HK_KHB_SET_HOTCOLD:
	      CM_READ_BE_UINT32(p,value,tmp);
	      status = KHB_SetSerialLine((CM_HOT_COLD)value);
	      HK_EndOfOp(status_ptr,status,taskid);
	      break;
	    case HK_KHB_GET_HOTCOLD:
	      CM_READ_BE_UINT32(p,value_ptr,tmp);
	      status = KHB_GetSerialLine((CM_HOT_COLD*)value_ptr);
	      HK_EndOfOp(status_ptr,status,taskid);
	      break;
	    default:
	    }
	}
    }
}


status_code HK_SendMsgAndWait(MsgTsk* Msg) {
  status_code status;
  rtems_event_set evout;
  /* clear the event before sending msg */
  OS_piEventClear(OS_EVENT_HK_DONE);
  /*send task msg*/
  status = HK_SndMsgHKManager(Msg);
  if(status==RTEMS_SUCCESSFUL)
    status = OS_piEventReceive(OS_EVENT_HK_DONE,RTEMS_WAIT, RTEMS_NO_TIMEOUT, &evout);

  return status;
}



status_code HK_SendTC(UINT32 code,UINT32 value)
{
  status_code status_sw,status = SUCCESSFUL; 
  MsgTsk HK_Msg;
  rtems_id taskid;
  BYTE *p;
  rtems_task_ident(RTEMS_SELF,RTEMS_SEARCH_ALL_NODES,&taskid);
  /*fill the task msg*/
  p = &HK_Msg.Info[0];  
  CM_WRITE_BE_UINT32(p,(UINT32)taskid);
  CM_WRITE_BE_UINT32(p,(UINT32)&status);
  CM_WRITE_BE_UINT32(p,code);
  CM_WRITE_BE_UINT32(p,value);
  HK_Msg.LlInfo = 16;
  HK_Msg.Code = HK_SEND_TC;

  status_sw = HK_SendMsgAndWait(&HK_Msg);
  if(status_sw != CM_RC_SUCCESSFUL)
    return status_sw;
  /* status has been set by the other task. if all is OK, return it */
  return(status);

}

status_code HK_GetTMValue(UINT32 code,UINT32 *value)
{
  status_code status_sw,status = SUCCESSFUL; 
  MsgTsk HK_Msg;
  rtems_id taskid;
  BYTE *p;
  rtems_event_set evout;
  rtems_task_ident(RTEMS_SELF,RTEMS_SEARCH_ALL_NODES,&taskid);
  /*fill the task msg*/
  p = &HK_Msg.Info[0];  
  CM_WRITE_BE_UINT32(p,(UINT32)taskid);
  CM_WRITE_BE_UINT32(p,(UINT32)&status);
  CM_WRITE_BE_UINT32(p,code);
  CM_WRITE_BE_UINT32(p,(UINT32)value);
  HK_Msg.LlInfo = 16;
  HK_Msg.Code = HK_GET_TM_VALUE;

  status_sw = HK_SendMsgAndWait(&HK_Msg);
  if(status_sw != CM_RC_SUCCESSFUL)
    return status_sw;
  /* status has been set by the other task. if all is OK, return it */
  return(status);
}


status_code HK_ReadKHBStatusRegister(UINT16 *value)
{
  status_code status_sw,status = SUCCESSFUL; 
  MsgTsk HK_Msg;
  rtems_id taskid;
  BYTE *p;
  rtems_event_set evout;
  rtems_task_ident(RTEMS_SELF,RTEMS_SEARCH_ALL_NODES,&taskid);
  /*fill the task msg*/
  p = &HK_Msg.Info[0];  
  CM_WRITE_BE_UINT32(p,(UINT32)taskid);
  CM_WRITE_BE_UINT32(p,(UINT32)&status);
  CM_WRITE_BE_UINT32(p,(UINT32)value);
  HK_Msg.LlInfo = 12;
  HK_Msg.Code = HK_KHB_READ_STATUS_REG;

  status_sw = HK_SendMsgAndWait(&HK_Msg);
  if(status_sw != CM_RC_SUCCESSFUL)
    return status_sw;
  /* status has been set by the other task. if all is OK, return it */
  return(status);
}

status_code HK_KHBSend128Trigger()
{
  status_code status_sw,status = SUCCESSFUL; 
  MsgTsk HK_Msg;
  rtems_id taskid;
  BYTE *p;
  rtems_event_set evout;
  rtems_task_ident(RTEMS_SELF,RTEMS_SEARCH_ALL_NODES,&taskid);
  /*fill the task msg*/
  p = &HK_Msg.Info[0];  
  CM_WRITE_BE_UINT32(p,(UINT32)taskid);
  CM_WRITE_BE_UINT32(p,(UINT32)&status);
  HK_Msg.LlInfo = 8;
  HK_Msg.Code = HK_KHB_SEND_128_TRIGGER;
  
  status_sw = HK_SendMsgAndWait(&HK_Msg);
  if(status_sw != CM_RC_SUCCESSFUL)
    return status_sw;
  /* status has been set by the other task. if all is OK, return it */
  return(status);
}


status_code HK_UpdateKHBMaskRegister(UINT16 value,BYTE action)
{
  status_code status_sw,status = SUCCESSFUL; 
  MsgTsk HK_Msg;
  rtems_id taskid;
  BYTE *p;
  rtems_event_set evout;
  rtems_task_ident(RTEMS_SELF,RTEMS_SEARCH_ALL_NODES,&taskid);
  /*fill the task msg*/
  p = &HK_Msg.Info[0];  
  CM_WRITE_BE_UINT32(p,(UINT32)taskid);
  CM_WRITE_BE_UINT32(p,(UINT32)&status);
  CM_WRITE_BE_UINT16(p,value);
  CM_WRITE_BE_UINT8(p,action);
  HK_Msg.LlInfo = 11;
  HK_Msg.Code = HK_KHB_UPDATE_MASK_REG;

  status_sw = HK_SendMsgAndWait(&HK_Msg);
  if(status_sw != CM_RC_SUCCESSFUL)
    return status_sw;
  /* status has been set by the other task. if all is OK, return it */
  return(status);
}


status_code HK_ReadKHBAlarmRegister(UINT32* mask)
{
  status_code status_sw,status = SUCCESSFUL; 
  MsgTsk HK_Msg;
  rtems_id taskid;
  BYTE *p;
  UINT32 tmp_mask;
  rtems_event_set evout;
  rtems_task_ident(RTEMS_SELF,RTEMS_SEARCH_ALL_NODES,&taskid);
  /*fill the task msg*/
  p = &HK_Msg.Info[0];  
  CM_WRITE_BE_UINT32(p,(UINT32)taskid);
  CM_WRITE_BE_UINT32(p,(UINT32)&status);
  CM_WRITE_BE_UINT32(p,(UINT32)&tmp_mask);
  HK_Msg.LlInfo = 12;
  HK_Msg.Code = HK_KHB_READ_ALARM_REG;

  status_sw = HK_SendMsgAndWait(&HK_Msg);
  if(status_sw==CM_RC_SUCCESSFUL)
    *mask=tmp_mask;
  else 
    return status_sw;
  /* status has been set by the other task. if all is OK, return it */
  return(status);
}

status_code HK_DoCyclicAcquisition(void *all_values_ptr)
{
  status_code status_sw,status = SUCCESSFUL; 
  MsgTsk HK_Msg;
  rtems_id taskid;
  BYTE *p;
  rtems_task_ident(RTEMS_SELF,RTEMS_SEARCH_ALL_NODES,&taskid);
  /*fill the task msg*/
  p = &HK_Msg.Info[0];  
  CM_WRITE_BE_UINT32(p,(UINT32)taskid);
  CM_WRITE_BE_UINT32(p,(UINT32)&status);
  CM_WRITE_BE_UINT32(p,(UINT32)all_values_ptr);
  HK_Msg.LlInfo = 12;
  HK_Msg.Code = HK_CYCLIC_ACQUISITION;

  status_sw = HK_SendMsgAndWait(&HK_Msg);
  if(status_sw != CM_RC_SUCCESSFUL)
    return status_sw;
  /* status has been set by the other task. if all is OK, return it */
  return(status);

}

status_code HK_SaveTMTCValues()
{
  status_code status_sw,status = SUCCESSFUL; 
  MsgTsk HK_Msg;
  rtems_id taskid;
  BYTE *p;
  rtems_task_ident(RTEMS_SELF,RTEMS_SEARCH_ALL_NODES,&taskid);
  /*fill the task msg*/
  p = &HK_Msg.Info[0];  
  CM_WRITE_BE_UINT32(p,(UINT32)taskid);
  CM_WRITE_BE_UINT32(p,(UINT32)&status);
  HK_Msg.LlInfo = 8;
  HK_Msg.Code = HK_SAVE_TMTC_VALUES;

  status_sw = HK_SendMsgAndWait(&HK_Msg);
  if(status_sw != CM_RC_SUCCESSFUL)
    return status_sw;
  /* status has been set by the other task. if all is OK, return it */
  return(status);

}

void HK_SendPoll_CallBack(rtems_id timer_id, void *suspend)
{
  static MsgTsk Msg;
  status_code status;

  Msg.Code = HK_POLL_KHB;
  status = HK_SndMsgHKManager(&Msg);
  
}



status_code HK_KHB_Cmd2FE(BYTE link,BYTE counter,BYTE expected,UINT16 *combuf,UINT16 *outbuf, UINT32 timeout)
{
  status_code status_sw,status = SUCCESSFUL; 
  MsgTsk HK_MsgToFe;
  rtems_id taskid;
  BYTE *p;
  rtems_task_ident(RTEMS_SELF,RTEMS_SEARCH_ALL_NODES,&taskid);
  /*fill the task msg*/
  p = &HK_MsgToFe.Info[0];  
  CM_WRITE_BE_UINT32(p,(UINT32)taskid);
  CM_WRITE_BE_UINT32(p,(UINT32)&status);
  CM_WRITE_BE_UINT8(p,counter);
  CM_WRITE_BE_UINT8(p,expected);
  CM_WRITE_BE_UINT8(p,link);
  CM_WRITE_BE_UINT32(p,(UINT32)outbuf);
  CM_WRITE_BE_UINT32(p,(UINT32)combuf);
  CM_WRITE_BE_UINT32(p,timeout);
  HK_MsgToFe.LlInfo = 23;
  HK_MsgToFe.Code = HK_KHB_FE_COM_BLOCK;

  status_sw = HK_SendMsgAndWait(&HK_MsgToFe);
  if(status_sw != CM_RC_SUCCESSFUL)
    return status_sw;
  /* status has been set by the other task. if all is OK, return it */
  return(status);
}


status_code HK_KHB_HardReset()
{
  status_code status_sw,status = SUCCESSFUL; 
  MsgTsk HK_Msg;
  rtems_id taskid;
  BYTE *p;

  rtems_task_ident(RTEMS_SELF,RTEMS_SEARCH_ALL_NODES,&taskid);
  /*fill the task msg*/
  p = &HK_Msg.Info[0];  
  CM_WRITE_BE_UINT32(p,(UINT32)taskid);
  CM_WRITE_BE_UINT32(p,(UINT32)&status);
  HK_Msg.LlInfo = 8;
  HK_Msg.Code = HK_KHB_HARD_RESET;

  status_sw = HK_SendMsgAndWait(&HK_Msg);

  if(status_sw != CM_RC_SUCCESSFUL)
    return status_sw;  
  
  return(status);
}


status_code HK_KHB_SetHotCold(CM_HOT_COLD hc)
{
  status_code status_sw,status = SUCCESSFUL; 
  MsgTsk HK_Msg;
  rtems_id taskid;
  BYTE *p;
  rtems_task_ident(RTEMS_SELF,RTEMS_SEARCH_ALL_NODES,&taskid);
  /*fill the task msg*/
  p = &HK_Msg.Info[0];  
  CM_WRITE_BE_UINT32(p,(UINT32)taskid);
  CM_WRITE_BE_UINT32(p,(UINT32)&status);
  CM_WRITE_BE_UINT32(p,(UINT32)hc);
  HK_Msg.LlInfo = 12;
  HK_Msg.Code =HK_KHB_SET_HOTCOLD; 

  status_sw = HK_SendMsgAndWait(&HK_Msg);

  if(status_sw != CM_RC_SUCCESSFUL)
    return status_sw;  
  
  return(status);
}

status_code HK_KHB_GetHotCold(CM_HOT_COLD *hc)
{
  status_code status_sw,status = SUCCESSFUL; 
  MsgTsk HK_Msg;
  rtems_id taskid;
  BYTE *p;
  rtems_task_ident(RTEMS_SELF,RTEMS_SEARCH_ALL_NODES,&taskid);
  /*fill the task msg*/
  p = &HK_Msg.Info[0];  
  CM_WRITE_BE_UINT32(p,(UINT32)taskid);
  CM_WRITE_BE_UINT32(p,(UINT32)&status);
  CM_WRITE_BE_UINT32(p,(UINT32)hc);
  HK_Msg.LlInfo = 12;
  HK_Msg.Code =HK_KHB_GET_HOTCOLD; 

  status_sw = HK_SendMsgAndWait(&HK_Msg);

  if(status_sw != CM_RC_SUCCESSFUL)
    return status_sw;  
  
  return(status);
}




status_code HK_KHB_InitBoard()
{
  status_code status_sw,status = SUCCESSFUL; 
  MsgTsk HK_Msg;
  rtems_id taskid;
  BYTE *p;
  rtems_task_ident(RTEMS_SELF,RTEMS_SEARCH_ALL_NODES,&taskid);
  /*fill the task msg*/
  p = &HK_Msg.Info[0];  
  CM_WRITE_BE_UINT32(p,(UINT32)taskid);
  CM_WRITE_BE_UINT32(p,(UINT32)&status);
  HK_Msg.LlInfo = 8;
  HK_Msg.Code = HK_KHB_INIT_BOARD;

  status_sw = HK_SendMsgAndWait(&HK_Msg);

  if(status_sw != CM_RC_SUCCESSFUL)
    return status_sw;  
  
  return(status);
}
