mirror of
https://github.com/nasa/trick.git
synced 2024-12-23 15:02:25 +00:00
19025d77ad
Reorganized. Created a new top level include directory that will hold all of Trick's header files. Moved all of the Trick headers to this directory. Created a libexec directory that holds all of the executables that users don't need to execute directly. Changed all of the executables remaining in bin to start with "trick-". In the sim_services directories changed all source files to find the Trick headers in their new location. Since all of the include files are gone in sim_services, removed the src directories as well, moving all of the source files up a level. Moved the makefiles, docs, man, and other architecture independent files into a top level share directory. Renamed lib_${TRICK_HOST_CPU} to lib64 or lib depending on the platform we're currently on. refs #63
172 lines
4.4 KiB
C++
172 lines
4.4 KiB
C++
/*
|
|
PURPOSE:
|
|
( gettimeofday clock )
|
|
PROGRAMMERS:
|
|
(((Alex Lin) (NASA) (Feb 2012) (--) (--)))
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "trick/BC635Clock.hh"
|
|
#include "trick/message_proto.h"
|
|
#include "trick/message_type.h"
|
|
#include "trick/release.h"
|
|
|
|
/**
|
|
@details
|
|
-# Calls the base Clock constructor
|
|
-# Sets the default device name
|
|
*/
|
|
Trick::BC635Clock::BC635Clock() : Clock(1000000, "BC635") {
|
|
#ifdef _BC635
|
|
mode = MODE_FREE ;
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
@details
|
|
-# This function is empty
|
|
*/
|
|
Trick::BC635Clock::~BC635Clock() { }
|
|
|
|
void Trick::BC635Clock::set_mode(unsigned int in_mode) {
|
|
mode = in_mode ;
|
|
}
|
|
|
|
unsigned int Trick::BC635Clock::get_mode() {
|
|
return mode ;
|
|
}
|
|
|
|
/**
|
|
@details
|
|
-# Opens the BC635 device
|
|
-# Returns error if unable to open device
|
|
-# Waits to be first user.
|
|
*/
|
|
int Trick::BC635Clock::clock_init() {
|
|
#ifdef _BC635
|
|
h_bc635 = bcStartPci();
|
|
|
|
if ( !h_bc635 ) {
|
|
message_publish( MSG_ERROR, "%s:%s:%d: Error on bcStartPci. Can't open Symmetricom BC635 PCI card.",
|
|
__FILE__, __FUNCTION__, __LINE__ );
|
|
return 1 ;
|
|
}
|
|
|
|
/* We have to use binary time in order to get sub-second time data */
|
|
if ( bcSetTimeFormat( h_bc635, FORMAT_BINARY ) == FALSE ) {
|
|
message_publish( MSG_ERROR, "bcSetTimeFormat failed" );
|
|
return -1 ;
|
|
}
|
|
|
|
/* Set the clock source to internal.. we're not using an external oscillator */
|
|
if ( bcSetClkSrc( h_bc635, CLK_INT) == FALSE ) {
|
|
message_publish( MSG_ERROR, "bcSetClkSrc failed to set the clock source to internal" );
|
|
return -1 ;
|
|
}
|
|
|
|
/* Sync the RTC to External Time Data */
|
|
if ( bcSyncRtc( h_bc635 ) == FALSE ) {
|
|
message_publish( MSG_ERROR, "bcSyncRtc failed to set the RTC to External Time Data" );
|
|
return -1 ;
|
|
}
|
|
|
|
/* Set the mode, e.g. to read input time codes, or freewheel */
|
|
/* (Note: This function returns void, so can't do error checking) */
|
|
bcSetMode( h_bc635, mode );
|
|
|
|
// Set local time offset to 0 (so we use GMT)
|
|
bcSetLocalOffsetFlag( h_bc635, LOCAL_OFF_DISABLE );
|
|
|
|
if ( bcSetGenCode( h_bc635, TCODE_IRIG_B ) == FALSE ) {
|
|
message_publish( MSG_ERROR, "bcSetGenCode failed to set output format to IRIG-B" );
|
|
return -1 ;
|
|
}
|
|
|
|
/* IRIG B002, B122 (BCD) */
|
|
if ( bcSetGenCodeEx( h_bc635, TCODE_IRIG_B, TCODE_IRIG_SUBTYPE_2 ) == FALSE ) {
|
|
message_publish( MSG_ERROR, "bcSetGenCodeEx failed to set output format to IRIG-B" );
|
|
return -1 ;
|
|
}
|
|
|
|
/* Set output frequency to 10Mhz */
|
|
DWORD ctlreg;
|
|
if ( bcReadReg( h_bc635, PCI_CONTROL_OFFSET, &ctlreg ) == FALSE ) {
|
|
message_publish( MSG_ERROR, "bcReadReg failed" );
|
|
return -1 ;
|
|
}
|
|
ctlreg &= 0x3F;
|
|
if ( bcWriteReg( h_bc635, PCI_CONTROL_OFFSET, ctlreg ) == FALSE ) {
|
|
message_publish( MSG_ERROR, "bcWriteReg failed" );
|
|
return -1 ;
|
|
}
|
|
|
|
set_global_clock() ;
|
|
|
|
return 0 ;
|
|
#else
|
|
message_publish(MSG_ERROR, "BC635 card was not enabled when Trick was compiled.\n\
|
|
Please run ${TRICK_HOME}/configure --bc635=<directory holding CTE>, and recompile Trick\n");
|
|
return -1 ;
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
@details
|
|
-# Gets the BC635 time.
|
|
-# If sucessful convert the BC635 time to tics
|
|
*/
|
|
long long Trick::BC635Clock::wall_clock_time() {
|
|
#ifdef _BC635
|
|
BOOL ret ;
|
|
DWORD ulpMaj, ulpMin ;
|
|
WORD ulpNano;
|
|
BYTE stat ;
|
|
long long curr_time ;
|
|
|
|
ret = bcReadBinTimeEx( h_bc635, &ulpMaj, &ulpMin, &ulpNano, &stat) ;
|
|
|
|
if ( ret == FALSE ) {
|
|
message_publish(MSG_ERROR, "Could not retrieve time from BC635\n") ;
|
|
} else {
|
|
// I believe that ulpMaj = num seconds and ulpMin is num microseconds. How convenient.
|
|
curr_time = (long long)ulpMaj * 1000000LL + ulpMin ;
|
|
}
|
|
|
|
return (curr_time);
|
|
#else
|
|
message_publish(MSG_ERROR, "BC635 card was not enabled at compile time\n");
|
|
return 0 ;
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
@details
|
|
-# Get the current real time.
|
|
-# While the current real time is less than the requested time
|
|
-# Release the processor momentarily
|
|
-# Get the current real time.
|
|
*/
|
|
long long Trick::BC635Clock::clock_spin(long long req_time) {
|
|
#ifdef _BC635
|
|
Trick::Clock::clock_spin(req_time) ;
|
|
#else
|
|
message_publish(MSG_ERROR, "BC635 card was not enabled at compile time\n");
|
|
return req_time ;
|
|
#endif
|
|
|
|
}
|
|
|
|
/**
|
|
@details
|
|
-# This function is empty
|
|
*/
|
|
int Trick::BC635Clock::clock_stop() {
|
|
#ifdef _BC635
|
|
// Don't do this because exec_terminate reads the time
|
|
//bcStopPci( h_bc635 );
|
|
#endif
|
|
return 0 ;
|
|
}
|
|
|