/**************************************************************************** /* F i l e D a t a /* /* Module : BasicSW /* C.I. No. : /* $Revision: 1.26 $ /* $Date: 2005/02/21 08:58:28 $ /* Belonging to : /* : /* $RCSfile: TI_TimingInfo_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: sebastiani $ /* : /**************************************************************************** /* U p d a t i n g /* /* $Log: TI_TimingInfo_op.c,v $ /* Revision 1.26 2005/02/21 08:58:28 sebastiani /* all log comments completed /* /* Revision 1.25 2005/02/19 10:16:47 sebastiani /* disable GPT /* /* Revision 1.24 2005/01/26 18:46:26 sebastiani /* *** empty log message *** /* /* Revision 1.23 2004/09/17 15:01:00 faber /* LU_INFN_LOG flags fixing /* /* Revision 1.22 2004/09/08 10:39:12 faber /* *** empty log message *** /* /* Revision 1.21 2004/08/26 16:54:01 sebastiani /* fix some bug /* /* Revision 1.20 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.19 2004/07/08 16:23:35 sebastiani /* *** empty log message *** /* /* Revision 1.18 2004/05/27 17:50:38 sebastiani /* *** empty log message *** /* /* Revision 1.17 2004/05/07 08:01:05 faber /* *** empty log message *** /* /* Revision 1.16 2004/05/06 15:50:57 faber /* GetTimeSyncInfo introduced /* /* Revision 1.15 2004/04/29 07:11:43 faber /* pached GetOrbitOffset /* /* Revision 1.14 2003/12/04 17:16:08 sebastiani /* GS debug/tests, and other /* /* Revision 1.13 2003/12/01 09:27:16 sebastiani /* CCA info for Gas Module and first implementation of IPM infos. /* /* Revision 1.12 2003/11/18 17:13:15 sebastiani /* GPT enabled to print a "\n" every 60s directly on UART, only to check if the CPU is /* alive /* /* Revision 1.11 2003/11/04 11:36:35 alfarano /* deleted task in TM_TMTC manager and added to HK_Manager, added KHB buffer read task /* /* Revision 1.10 2003/10/30 16:10:48 faber /* GPT disabled. the callback function is a null function /* /* Revision 1.9 2003/10/21 16:09:12 alfarano /* LU_LOG_INFN replacement for all remaining original log functions /* /* Revision 1.8 2003/09/15 09:20:23 faber /* GTP function modification for simulator mode (TimedFunction) /* /* Revision 1.7 2003/09/12 10:52:56 faber /* introduced PTH_VAR_TC_CYC_RATE /* /* Revision 1.6 2003/09/10 16:15:51 faber /* PRH_EXTERN_VAR(XX_LOGMASK) removed (not needed any more) /* /* Revision 1.5 2003/09/10 11:55:07 faber /* LU_MASK introduced. Log mask for module is now an unique array (PRH_ARR_LOG_MASK) indexed by __FILEID__ /* /* Revision 1.4 2003/08/29 11:13:30 faber /* TI_StartTimerMoscowTime introduced /* /* Revision 1.3 2003/08/28 10:11:44 faber /* New timer management. GPT is now possible to be disabled. (DisableGPT,EnableGPT) /* GetTimeInfo now use the RTEMS clock instead reading the TI_SystemTime. /* GetTimeInfo now returns seconds, instead of milliseconds. /* /* Revision 1.2 2003/08/22 07:47:35 sebastiani /* Timer behavior change: TYME_SYNC / OBT_ORBIT / OBT introduced. /* TymeSync MCMD now doesn't affect OBT (TI_SystemTime) any more /* /* Revision 1.1.1.1 2003/08/04 09:40:21 sebastiani /* Imported sources laben rel. 19.06.2003 integrated with pam2 /* /* Revision 1.2 2003/06/18 16:53:19 sebastiani /* Pam/Run Manager development update. ExpSeq sequence is receiven from the RunManager (simulator mode) /* /* Revision 1.1.1.1 2003/05/27 08:13:24 wizard /* Import of the Official Laben CD Release Software as the pamela-EM_delivery_20030521_1454.tar.bz2 /* /* Revision 1.9 2003/01/30 09:43:49 aurora /* introduced ifdef for EM and FM /* /* Revision 1.8 2002/11/14 09:46:42 zulia /* removed unsed status variable /* /* Revision 1.7 2002/09/11 15:34:17 zulia /* comment /* /* Revision 1.6 2002/05/09 08:16:34 zulia /* * acceptance release /* /* /*****************************************************************************/ /*============================= Include File ================================*/ #include #define __FILEID__ _TI_TimingInfo_op__c #include #include #include LU_DECL_MASK(); #include #include //##FS 17.6.03 #ifdef SIMULATOR #include #endif //##FS END 17.6.03 /*****************************************************************************/ /*============================= Object variables ============================*/ /*****************************************************************************/ /* @Variable: TI_ObtTimeSync */ /* @Purpose : */ /* TI_TIME type */ /* is the OBT in the moment in which the Time Sync MCMD arrived. */ /* if zero, means not set. */ /* in milliseconds */ /* @@ */ /*****************************************************************************/ static TI_TIME TI_ObtTimeSync_s; static TI_TIME TI_ObtTimeSync_ms; volatile static BOOL TimeSyncExtInt_enabled = FALSE; /*****************************************************************************/ /* @Variable: TI_TimeSync */ /* @Purpose : */ /* TI_TIME type */ /* is the "Moscow Time" arrived by the MCMD */ /* if zero, means not set. */ /* in seconds */ /* @@ */ /*****************************************************************************/ static TI_TIME TI_TimeSync_s; /*****************************************************************************/ /* @Variable: TI_ObtOrbit */ /* @Purpose : */ /* TI_TIME type */ /* is the OBT in the moment of the Ascending Node (CALIBRATE MCMD) */ /* To know the tim of the (last) ascending node, calculate: */ /* OBT - ObtOrbit */ /* zero means not set. */ /* in seconds */ /* @@ */ /*****************************************************************************/ static TI_TIME TI_ObtOrbit_s; /*****************************************************************************/ /* @Variable: TI_TimeSyncCounter */ /* @Purpose : */ /* unsigned int type */ /* store the number times the TimeSync MCMD was received. */ /* if zero means that the Time Sync */ /* MCMD has never arrived (in this case time-variables should be TI_UNSET).*/ /* in seconds */ /* @@ */ /*****************************************************************************/ static unsigned int TI_TimeSyncCounter; /*===========================================================================*/ /* External Parameters */ /*****************************************************************************/ /*===== T i m i n g I n f o O P E R A T I O N A L F U N C T I O N S =====*/ /*****************************************************************************/ /* @Function: TI_opInitTimingInfo */ /* @Purpose : */ /* The function performs the following initialization: */ /* - Establishes an ISR for ERC 32 General Purpos Timer (GPT). */ /* - Initializes the GPT Scaler and Couter. */ /* - Initializes global object variables. */ /* */ /* @@ */ /* @Parameter Name @Mode @Description */ /* @@ */ /*****************************************************************************/ status_code TI_opInitTimingInfo (void) { status_code status; void* OldHandler; /* the rtems epoch is 01.01.1988 00:00 */ static rtems_time_of_day epoch = {1988,1,1,0,0,0,0}; /*===========================================================================*/ /*================ GENERAL PURPOSE TIMER (ERC32) ========================*/ /* status =OS_piIsrCatch ( TI_opNull, ERC32_INTERRUPT_GENERAL_PURPOSE_TIMER+0x10, &OldHandler); */ #if TI_GPT_ENABLED status =OS_piIsrCatch ( TI_ihTimingInfo, ERC32_INTERRUPT_GENERAL_PURPOSE_TIMER+0x10, &OldHandler); if (status==SUCCESSFUL) { /*==== INIT OF THE GENERAL PURPOSE TIMER (ERC32) ====================*/ ERC32_MEC.General_Purpose_Timer_Counter =TI_GPT_COUNTER_VALUE*1000*5; ERC32_MEC.General_Purpose_Timer_Scalar =TI_GPT_SCALER_VALUE; ERC32_MEC_Set_General_Purpose_Timer_Control( ERC32_MEC_TIMER_COUNTER_RELOAD_AT_ZERO | ERC32_MEC_TIMER_COUNTER_LOAD_COUNTER | ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING | ERC32_MEC_TIMER_COUNTER_LOAD_SCALER); TI_opEnableGPT(); } else { /* ISR not successfully established */ // LOG_INFN HA_piLogHistoryEntry10(HA_E10_SW_TI,HA_E10_INT_CATCH_ERR,status); /*@LOG Isr not successfully enstablisched - status */ LU_INFN_LOG(LU_FATAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status); } #else TI_opDisableGPT(); #endif /*===========================================================================*/ /*=================== SYSTEM TIME INITIALIZATION ========================*/ TI_ObtTimeSync_s =TI_UNSET; TI_ObtTimeSync_ms =TI_UNSET; TI_TimeSync_s =TI_UNSET; TI_ObtOrbit_s =TI_UNSET; TI_TimeSyncCounter = 0; /* init the RTEMS system clock to the RTEMS epoch: */ status = rtems_clock_set(&epoch); if(status) /*@LOG invalid time of day - statys */ LU_INFN_LOG(LU_FATAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status); return (status); } /*****************************************************************************/ /* @Function: TI_OBT */ /* @Purpose : */ /* Get the OBT using the rtems clock. The function returns the number of */ /* seconds since bootstrap (pamela initialization) */ /*****************************************************************************/ static TI_TIME TI_OBT_s() { rtems_interval sse; rtems_clock_get(RTEMS_CLOCK_GET_SECONDS_SINCE_EPOCH,&sse); /* TI_TIME is unsigned long (uint32). rtems_interval is unsigned32 too. */ return sse; } static TI_TIME TI_OBT_ms() { rtems_clock_time_value t; rtems_clock_get(RTEMS_CLOCK_GET_TIME_VALUE,&t); return (t.seconds*1000)+(t.microseconds/1000); } void TI_opDisableGPT() { ERC32_Mask_interrupt( ERC32_INTERRUPT_GENERAL_PURPOSE_TIMER ); } void TI_opEnableGPT() { ERC32_Unmask_interrupt( ERC32_INTERRUPT_GENERAL_PURPOSE_TIMER ); } /*****************************************************************************/ /* @Function: TI_opTimingOperation */ /* @Purpose : */ /* The function implements the OBT interrupt handler. The interrupt rate */ /* is every 1 ms. The function provides for the following actions: */ /* - Increment the variable TI_SystemTime (OBT). */ /* - Decrement the Monitoring counter, and whenever this counter goes to */ /* zero (every second) send a message to Monitoring to start parameters */ /* check. */ /* - Send message to TTMANAGER every 128 ms for MCMD timetag. */ /* check. */ /* */ /* @@ */ /* @Parameter Name @Mode @Description */ /* @@ */ /*****************************************************************************/ void TI_opNull(void) { return; } void TI_opTimingOperation (void) { // MsgTsk SndMsg; static unsigned int t=0; t++; console_outbyte_polled(0,'-'); console_outbyte_polled(0,'0'+t%10); console_outbyte_polled(0,'\n'); LU_UART_CR('-'); #ifdef SIMULATOR PM_SendTestCommand(105,0,0,0,0); #endif /* if(TI_SystemTime == MAX_SYSTEM_TIME) { TI_SystemTimeRestart++; TI_SystemTime=1; LU_INFN_LOG(LU_WARNING,LU_MASK(__FILEID__),__FILEID__,__LINE__,TI_SystemTimeRestart ); } */ } /*****************************************************************************/ /* @Function: TI_opGetTimeInfo */ /* @Purpose : */ /* The function returns the On Board Time (OBT) information. */ /* */ /* @@ */ /* @Parameter Name @Mode @Description */ /* IN */ /* status_code OUT Return code */ /* @@ */ /*****************************************************************************/ void TI_opGetTimeInfo_s (TI_TIME* Time) { *Time = TI_OBT_s(); } void TI_opGetTimeInfo_ms (TI_TIME* Time) { *Time = TI_OBT_ms(); } status_code TI_opResourceObtain() { status_code s; if(rtems_interrupt_is_in_progress()) return TI_SUCCESSFUL; s=OS_piResourceObtain(TI_RES,WAIT,NO_TIMEOUT); if(s != SUCCESSFUL) { /*@LOG TI_opResourceObtain(): error - status */ LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,s); s=TI_RESERROR; }else s=TI_SUCCESSFUL; return s; } status_code TI_opResourceRelease() { status_code s; if(rtems_interrupt_is_in_progress()) return TI_SUCCESSFUL; s=OS_piResourceRelease(TI_RES); if(s != SUCCESSFUL) { /*@LOG TI_opResourceRelease(): error - status */ LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,s); s=TI_RESERROR; }else s=TI_SUCCESSFUL; return s; } void TI_opSetObtTimeSync(TI_TIME ms,BOOL enable_next) { UINT32 intLevel; OS_PROTECTED_INT(intLevel, do { if(TimeSyncExtInt_enabled) { TI_ObtTimeSync_ms = ms; TI_ObtTimeSync_s = ms / 1000; TimeSyncExtInt_enabled = enable_next; } } while(0) ); } void TI_opTimeSyncExtInterrupt() { volatile BOOL doit; UINT32 intLevel; OS_PROTECTED_INT(intLevel,doit = TimeSyncExtInt_enabled); if(doit) TI_opSetObtTimeSync(TI_OBT_ms(),FALSE); } /*****************************************************************************/ /* @Function: TI_opUpdateTimeInfo */ /* @Purpose : */ /* The function updates the Time Information when a TimeSync MCMD arrive. */ /* */ /* @@ */ /* @Parameter Name @Mode @Description */ /* Time IN The "Moscow Time" in seconds */ /* @@ */ /*****************************************************************************/ void TI_opUpdateTimeInfo_s (TI_TIME Time) { UINT32 intLevel; OS_PROTECTED_INT(intLevel,TimeSyncExtInt_enabled = TRUE); if( (TI_opResourceObtain()) == SUCCESSFUL) { TI_TimeSyncCounter++; TI_TimeSync_s = Time; /* this is incorrect, but it will fix if the interrupt will not come: */ TI_opSetObtTimeSync(TI_OBT_ms(),TRUE); OS_PROTECTED_INT(intLevel,TimeSyncExtInt_enabled = TRUE); } TI_opResourceRelease(); } /*****************************************************************************/ /* @Function: TI_GetTimeSyncInfo */ /* @Purpose : */ /* The function return the time sync infos stored wten the time sync arrived*/ /* if info is not available, put 0 into both output params and return error */ /* @@ */ /* @Parameter Name @Mode @Description */ /* OBT OUT OBT at the moment of the TSYNC */ /* TimeSync OUT MoscowTime arrived */ /* @@ */ /*****************************************************************************/ status_code TI_opGetTimeSyncInfo_s(TI_TIME *obt_ts,TI_TIME *ts) { status_code status; volatile TI_TIME TI_ObtTimeSync_s_local; UINT32 intLevel; if( (status=TI_opResourceObtain()) == SUCCESSFUL) { if(TI_TimeSyncCounter > 0) { OS_PROTECTED_INT(intLevel,TI_ObtTimeSync_s_local = TI_ObtTimeSync_s); *obt_ts = TI_ObtTimeSync_s_local; *ts = TI_TimeSync_s; status=TI_SUCCESSFUL; } else { status=TI_NOTIMESYNC; *obt_ts = 0; *ts = 0; } } if(TI_opResourceRelease() == TI_RESERROR) status = TI_RESERROR; return status; } /*****************************************************************************/ /* @Function: TI_GetTimeSyncOffset */ /* @Purpose : */ /* The function return the TIME_SYNC_OFFSET that is TI_OBT - */ /* TI_ObtTimeSync. */ /* @@ */ /* @Parameter Name @Mode @Description */ /* Time IN The "Moscow Time" in seconds */ /* @@ */ /*****************************************************************************/ status_code TI_opGetTimeSyncOffset_s(TI_TIME *t) { status_code status; volatile TI_TIME TI_ObtTimeSync_s_local; UINT32 intLevel; if( (status=TI_opResourceObtain()) == SUCCESSFUL) { if(TI_TimeSyncCounter > 0) { OS_PROTECTED_INT(intLevel,TI_ObtTimeSync_s_local = TI_ObtTimeSync_s); *t = TI_OBT_s() - TI_ObtTimeSync_s_local; status=TI_SUCCESSFUL; } else status=TI_NOTIMESYNC; } if(TI_opResourceRelease() == TI_RESERROR) status = TI_RESERROR; return status; } /*****************************************************************************/ /* @Function: TI_GetCurrentMoscowTime */ /* @Purpose : */ /* The current moscow time is the TimeSync plus the "time sync offset", */ /* that is TI_OBT - TI_ObtTimeSync */ /* @@ */ /* @Parameter Name @Mode @Description */ /* t OUT The "Moscow Time" in seconds */ /* @@ */ /*****************************************************************************/ status_code TI_opGetCurrentMoscowTime_s(TI_TIME *t) { status_code status; volatile TI_TIME TI_ObtTimeSync_s_local; UINT32 intLevel; if( (status=TI_opResourceObtain()) == SUCCESSFUL) { if(TI_TimeSyncCounter != 0) { OS_PROTECTED_INT(intLevel,TI_ObtTimeSync_s_local = TI_ObtTimeSync_s); *t = TI_TimeSync_s + (TI_OBT_s() - TI_ObtTimeSync_s_local); status=TI_SUCCESSFUL; } else { *t = 0; status=TI_NOTIMESYNC; } } if(TI_opResourceRelease() == TI_RESERROR) status = TI_RESERROR; return status; } /*****************************************************************************/ /* @Function: TI_TimeSyncIsAvailable */ /* @Purpose : */ /* The information of the TimeSync is available if UpdateTimeInfo has called*/ /* at least one time, that means a TimeSync MCMD was coming. */ /* if TI_TimeSyncCounter == 0, then the information is not available. */ /* @@ */ /* @Parameter Name @Mode @Description */ /* t OUT The "Moscow Time" in seconds */ /* @@ */ /*****************************************************************************/ status_code TI_opTimeSyncIsAvailable(BOOL* avail) { status_code status; if( (status=TI_opResourceObtain()) == SUCCESSFUL) { *avail = (TI_TimeSyncCounter != 0); } if(TI_opResourceRelease() == TI_RESERROR) status = TI_RESERROR; return status; } /*****************************************************************************/ /* @Function: TI_SetObtOrbit */ /* @Purpose : */ /* The TI_ObtOrbit is defined to be the OBT (TI_OBT) in the moment */ /* of the ascending node. This function sets the TI_ObtOrbit properly and */ /* it sshould be called only when the */ /* ascending node MCMD (CALIBRATE) cames. */ /* @@ */ /* @Parameter Name @Mode @Description */ /* t OUT The "Moscow Time" in seconds */ /* @@ */ /*****************************************************************************/ status_code TI_opSetObtOrbit_s() { status_code status; if( (status=TI_opResourceObtain()) == SUCCESSFUL) { TI_ObtOrbit_s = TI_OBT_s(); } if(TI_opResourceRelease() == TI_RESERROR) status = TI_RESERROR; return status; } status_code TI_opGetObtOrbit_s(TI_TIME* t) { status_code status; if( (status=TI_opResourceObtain()) == SUCCESSFUL) { if(TI_ObtOrbit_s != TI_UNSET) { *t=TI_ObtOrbit_s; status=TI_SUCCESSFUL; }else status=TI_NOORBIT; } if(TI_opResourceRelease() == TI_RESERROR) status = TI_RESERROR; return status; } /*****************************************************************************/ /* @Function: TI_GetOrbitOffset */ /* @Purpose : */ /* The Orbit Offset is the time in seconds elapsed since the last ascendind */ /* node (CALIBRATE) MCMD */ /* that is TI_OBT-TI_ObtOrbit */ /* @@ */ /* @Parameter Name @Mode @Description */ /* @@ */ /*****************************************************************************/ status_code TI_opGetOrbitOffset_s(TI_TIME *t) { status_code status; if( (status=TI_opResourceObtain()) == SUCCESSFUL) { if(TI_ObtOrbit_s != TI_UNSET) { *t = TI_OBT_s() - TI_ObtOrbit_s; status=TI_SUCCESSFUL; }else status=TI_NOORBIT; } if(TI_opResourceRelease() == TI_RESERROR) status = TI_RESERROR; return status; } /*****************************************************************************/ /* @Function: TI_StartTimerMoscowTime */ /* @Purpose : */ /* This function is a wrapper of the OS_StartTimer_INFN function. */ /* but the time info is expressed in absolute MoscowTime. */ /* the function computes the remaining time before the event, */ /* if the time is elapled (belong into the past, the function return */ /* TI_ELAPSED */ /* if the OS_StartTimer returns an error, its logged and return */ /* TI_TIMERERROR */ /* this function cannot be called into an ISR becasue the semaphore */ /* @@ */ /* @Parameter Name @Mode @Description */ /* t OUT The "Moscow Time" in seconds */ /* @@ */ /*****************************************************************************/ status_code TI_opStartTimer_INFN_MoscowTime_s(unsigned int Tim,TI_TIME Time,void* Routine,void* UserData) { status_code status; TI_TIME now,after; status = TI_opGetCurrentMoscowTime_s(&now); if(status == TI_SUCCESSFUL) { if(now > Time) /* time is elapsed */ status = TI_ELAPSED; else { after = Time - now; status = OS_piStartTimer_INFN (Tim,after,Routine,UserData); if (status != SUCCESSFUL) { /*@LOG StartTimer_INFN error - status */ LU_INFN_LOG(LU_CRITICAL|LU_HA,LU_MASK(__FILEID__),__FILEID__,__LINE__,status); status=TI_TIMERERROR; } } } return status; }