Commit 97bcfc1e authored by Rolf Bork's avatar Rolf Bork

Merge branch 'virtualmach'

parents d658561f e65187bd
......@@ -128,6 +128,7 @@ $flipSignals = 0;
$ipcrate = 0;
$ipccycle = 0;
$virtualiop = 0;
$force_shm_ipc = 0;
$no_cpu_shutdown = 0;
$edcu = 0;
$casdf = 0;
......@@ -1802,20 +1803,10 @@ print "\tPart number is $remoteGpsPart\n";
}
if($virtualiop == 1) {
print OUT "#include \"$rcg_src_dir/src/fe/controllerVirtual.c\"\n";
} elsif ($virtualiop == 2) {
print OUT "#include \"$rcg_src_dir/src/fe/controllerIop.c\"\n";
} elsif ($virtualiop == 3) {
print OUT "#include \"$rcg_src_dir/src/fe/controllerLR.c\"\n";
} elsif ($virtualiop == 4) {
print OUT "#include \"$rcg_src_dir/src/fe/controllerCymac.c\"\n";
if($adcMaster == 1) {
print OUT "#include \"$rcg_src_dir/src/fe/controllerIop.c\"\n";
} else {
if($adcMaster == 1) {
print OUT "#include \"$rcg_src_dir/src/fe/controllerIop.c\"\n";
} else {
print OUT "#include \"$rcg_src_dir/src/fe/controllerApp.c\"\n";
}
}
......@@ -2499,6 +2490,7 @@ sub createEpicsMakefile {
#// Generate the user C code Makefile \n\n
sub createCmakefile{
# Compile options common to all runtime configurations
system ("/bin/cp GNUmakefile ../../fe/$skeleton");
open(OUTM,">./".$mFile) || die "cannot open Makefile file for writing";
......@@ -2526,8 +2518,8 @@ print OUTM "\U$skeleton";
print OUTM "_CODE\n";
print OUTM "EXTRA_CFLAGS += -DFE_SRC=\\\"\L$skeleton/\L$skeleton.c\\\"\n";
print OUTM "EXTRA_CFLAGS += -DFE_HEADER=\\\"\L$skeleton.h\\\"\n";
#print OUTM "EXTRA_CFLAGS += -DFE_PROC_FILE=\\\"\L${skeleton}_proc.h\\\"\n";
# Model uses FIR filters
if($systemName eq "sei" || $useFIRs)
{
print OUTM "EXTRA_CFLAGS += -DFIR_FILTERS\n";
......@@ -2547,13 +2539,6 @@ if ($requireIOcnt) {
print OUTM "#Uncomment to enable exact IO module count requirement\n";
print OUTM "#EXTRA_CFLAGS += -DREQUIRE_IO_CNT\n";
}
if ($no_sync) {
print OUTM "#Comment out to enable 1PPS synchronization\n";
print OUTM "EXTRA_CFLAGS += -DNO_SYNC\n";
} else {
print OUTM "#Uncomment to disable 1PPS signal sinchronization (channel 31 (last), ADC 0)\n";
print OUTM "#EXTRA_CFLAGS += -DNO_SYNC\n";
}
if (0 == $dac_testpoint_names && 0 == $::extraTestPoints && 0 == $filtCnt) {
print "Not compiling DAQ into the front-end\n";
$no_daq = 1;
......@@ -2590,6 +2575,26 @@ if($rate > 15) {
}
}
}
# Set to flip polarity of ADC input signals
if ($flipSignals) {
print OUTM "EXTRA_CFLAGS += -DFLIP_SIGNALS=1\n";
}
# Set CPU core for runtime
if ($specificCpu > -1) {
print OUTM "#Comment out to run on first available CPU\n";
print OUTM "EXTRA_CFLAGS += -DSPECIFIC_CPU=$specificCpu\n";
}
# Set BIQUAD as default starting RCG V2.8
print OUTM "EXTRA_CFLAGS += -DALL_BIQUAD=1 -DCORE_BIQUAD=1\n";
if ($::rfmDelay) {
print OUTM "#Comment out to run without RFM Delayed by 1 cycle\n";
print OUTM "EXTRA_CFLAGS += -DRFM_DELAY=1\n";
}
#********* END OF COMMON COMPILE OPTIONS
if ($adcMaster > -1) { #************ SETUP FOR IOP ***************
print OUTM "EXTRA_CFLAGS += -DADC_MASTER\n";
$modelType = "MASTER";
......@@ -2608,45 +2613,35 @@ if ($adcMaster > -1) { #************ SETUP FOR IOP ***************
#Following set to run as standard kernel module
if ($no_cpu_shutdown > 0) {
print OUTM "EXTRA_CFLAGS += -DNO_CPU_SHUTDOWN\n";
} else {
print OUTM "#EXTRA_CFLAGS += -DNO_CPU_SHUTDOWN\n";
}
# ADD DAC_AUTOCAL to IOPs
print OUTM "EXTRA_CFLAGS += -DDAC_AUTOCAL\n";
} else {
print OUTM "#Uncomment to run on an I/O Master \n";
print OUTM "#EXTRA_CFLAGS += -DADC_MASTER\n";
}
if ($adcSlave > -1) { #************ SETUP FOR USER APP ***************
print OUTM "EXTRA_CFLAGS += -DADC_SLAVE\n";
print OUTM "EXTRA_CFLAGS += -DUNDERSAMPLE=1\n";
print OUTM "EXTRA_CFLAGS += -DADC_MEMCPY_RATE=1\n";
$modelType = "SLAVE";
} else {
print OUTM "#Uncomment to run on an I/O slave process\n";
print OUTM "#EXTRA_CFLAGS += -DADC_SLAVE\n";
}
if ($timeMaster > -1) {
print OUTM "EXTRA_CFLAGS += -DTIME_MASTER=1\n";
} else {
print OUTM "#Uncomment to build a time master\n";
print OUTM "#EXTRA_CFLAGS += -DTIME_MASTER=1\n";
}
if ($timeSlave > -1 or $virtualiop == 2) {
print OUTM "EXTRA_CFLAGS += -DTIME_SLAVE=1\n";
} else {
print OUTM "#Uncomment to build a time slave\n";
print OUTM "#EXTRA_CFLAGS += -DTIME_SLAVE=1\n";
}
if ($rfmTimeSlave > -1) {
print OUTM "EXTRA_CFLAGS += -DRFM_TIME_SLAVE=1\n";
} else {
print OUTM "#Uncomment to build an RFM time slave\n";
print OUTM "#EXTRA_CFLAGS += -DRFM_TIME_SLAVE=1\n";
}
if ($flipSignals) {
print OUTM "EXTRA_CFLAGS += -DFLIP_SIGNALS=1\n";
}
if ($pciNet > 0) {
# Set to run without LIGO timing system
if ($no_sync) {
print OUTM "#Comment out to enable 1PPS synchronization\n";
print OUTM "EXTRA_CFLAGS += -DNO_SYNC\n";
}
# Set to run IOP as time master for the Dolphin Network
if ($timeMaster > -1) {
print OUTM "EXTRA_CFLAGS += -DTIME_MASTER=1\n";
}
# Set to run IOP as time slave on the Dolphin Network
if ($timeSlave > -1 or $virtualiop == 2) {
print OUTM "EXTRA_CFLAGS += -DTIME_SLAVE=1\n";
print OUTM "EXTRA_CFLAGS += -DNO_DAC_PRELOAD=1\n";
}
# Set to run IOP on internal clock ie no IO modules
if ($virtualiop == 1) {
print OUTM "EXTRA_CFLAGS += -DRUN_WO_IO_MODULES=1\n";
print OUTM "EXTRA_CFLAGS += -DNO_DAC_PRELOAD=1\n";
}
# Set IOP to map Dolphin Networks
# Dolphin Gen2 is the default
if ($virtualiop != 1) {
if ($pciNet > 0) {
if ($dolphinGen == 2) {
print OUTM "#Enable use of PCIe RFM Network Gen 2\n";
print OUTM "DISDIR = /opt/srcdis\n";
......@@ -2658,53 +2653,26 @@ if ($pciNet > 0) {
print OUTM "KBUILD_EXTRA_SYMBOLS += \$(DISDIR)/src/SCI_SOCKET/ksocket/lib/LINUX/Module.symvers\n";
print OUTM "EXTRA_CFLAGS += -DOS_IS_LINUX=1 -D_KERNEL=1 -I\$(DISDIR)/src/IRM/drv/src -I\$(DISDIR)/src/IRM/drv/src/LINUX -I\$(DISDIR)/src/include -I\$(DISDIR)/src/include/dis -DDOLPHIN_TEST=1 -DDIS_BROADCAST=0x80000000\n";
}
}
if ($specificCpu > -1) {
print OUTM "#Comment out to run on first available CPU\n";
print OUTM "EXTRA_CFLAGS += -DSPECIFIC_CPU=$specificCpu\n";
} else {
print OUTM "#Uncomment to run on a specific CPU\n";
print OUTM "#EXTRA_CFLAGS += -DSPECIFIC_CPU=2\n";
}
# Set BIQUAD as default starting RCG V2.8
print OUTM "#Comment out to go back to old iir_filter calculation form\n";
print OUTM "EXTRA_CFLAGS += -DALL_BIQUAD=1 -DCORE_BIQUAD=1\n";
if ($::directDacWrite) {
print OUTM "EXTRA_CFLAGS += -DDIRECT_DAC_WRITE=1\n";
} else {
print OUTM "#EXTRA_CFLAGS += -DDIRECT_DAC_WRITE=1\n";
}
}
}
if ($::noZeroPad) {
print OUTM "EXTRA_CFLAGS += -DNO_ZERO_PAD=1\n";
} else {
print OUTM "#EXTRA_CFLAGS += -DNO_ZERO_PAD=1\n";
if ($::optimizeIO) {
print OUTM "EXTRA_CFLAGS += -DNO_DAC_PRELOAD=1\n";
}
}
# End of IOP compile options
if ($::optimizeIO) {
print OUTM "EXTRA_CFLAGS += -DNO_DAC_PRELOAD=1\n";
} else {
print OUTM "#EXTRA_CFLAGS += -DNO_DAC_PRELOAD=1\n";
}
if ($adcSlave > -1) { #************ SETUP FOR USER APP ***************
print OUTM "EXTRA_CFLAGS += -DADC_SLAVE\n";
print OUTM "EXTRA_CFLAGS += -DUNDERSAMPLE=1\n";
print OUTM "EXTRA_CFLAGS += -DADC_MEMCPY_RATE=1\n";
$modelType = "SLAVE";
if ($::rfmDma) {
print OUTM "#Comment out to run with RFM DMA\n";
print OUTM "#EXTRA_CFLAGS += -DRFM_DIRECT_READ=1\n";
} else {
print OUTM "#Comment out to run with RFM DMA\n";
print OUTM "EXTRA_CFLAGS += -DRFM_DIRECT_READ=1\n";
if ($::noZeroPad) {
print OUTM "EXTRA_CFLAGS += -DNO_ZERO_PAD=1\n";
}
}
if ($::rfmDelay) {
print OUTM "#Comment out to run without RFM Delayed by 1 cycle\n";
print OUTM "EXTRA_CFLAGS += -DRFM_DELAY=1\n";
} else {
print OUTM "#Clear comment to run with RFM Delayed by 1 cycle\n";
print OUTM "#EXTRA_CFLAGS += -DRFM_DELAY=1\n";
}
print OUTM "\n";
......@@ -2849,11 +2817,13 @@ if ($flipSignals) {
print OUTM "CFLAGS += -DFLIP_SIGNALS=1\n";
}
if ($virtualiop != 1) {
if ($pciNet > 0) {
print OUTM "#Enable use of PCIe RFM Network Gen 2\n";
print OUTM "DOLPHIN_PATH = /opt/srcdis\n";
print OUTM "CFLAGS += -DHAVE_CONFIG_H -I\$(DOLPHIN_PATH)/src/include/dis -I\$(DOLPHIN_PATH)/src/include -I\$(DOLPHIN_PATH)/src/SISCI/cmd/test/lib -I\$(DOLPHIN_PATH)/src/SISCI/src -I\$(DOLPHIN_PATH)/src/SISCI/api -I\$(DOLPHIN_PATH)/src/SISCI/cmd/include -I\$(DOLPHIN_PATH)/src/IRM_GX/drv/src -I\$(DOLPHIN_PATH)/src/IRM_GX/drv/src/LINUX -DOS_IS_LINUX=196616 -DLINUX -DUNIX -DLITTLE_ENDIAN -DDIS_LITTLE_ENDIAN -DCPU_WORD_IS_64_BIT -DCPU_ADDR_IS_64_BIT -DCPU_WORD_SIZE=64 -DCPU_ADDR_SIZE=64 -DCPU_ARCH_IS_X86_64 -DADAPTER_IS_IX -m64 -D_REENTRANT\n";
}
}
if ($specificCpu > -1) {
print OUTM "#Comment out to run on first available CPU\n";
......@@ -2916,7 +2886,7 @@ print OUTM "\n";
print OUTM "\n";
print OUTM "CFLAGS += -I\$(SUBDIRS)/../../include -I$rcg_src_dir\/src/drv -I$rcg_src_dir\/src/include \n";
if ($pciNet > 0) {
if ($pciNet > 0 && $virtualiop != 1) {
print OUTM "LDFLAGS = -L \$(API_LIB_PATH) -lsisci\n";
} else {
print OUTM "LDFLAGS = -L \$(API_LIB_PATH) \n";
......
......@@ -281,7 +281,11 @@ for ($ii = 0; $ii < $i; $ii++) {
if ($::partType[$ii] =~ /^IPCx/) {
# Add signal name to info table
$::ipcxParts[$::ipcxCnt][0] = $::xpartName[$ii];
print "$::ipcxBlockTags[$ii] \n";
if ($::virtualiop == 1 or $::force_shm_ipc) {
$::ipcxBlockTags[$ii] = "cdsIPCx_SHMEM";
}
$::ipcxCommMech = substr($::ipcxBlockTags[$ii], 8, 4);
# Add IPC net type to info table
$::ipcxParts[$::ipcxCnt][1] = "I" . $::ipcxCommMech;
......@@ -486,7 +490,7 @@ $ipcxRcvrCnt = 0;
$typeComp = $::ipcxParts[$ii][1];
if ($ipcxData[$jj][1] ne $typeComp) {
die "***ERROR: IPCx type mis-match for IPCx component $::ipcxParts[$ii][0] $::ipcxParts[$ii][1] : $typeComp vs\. $ipcxData[$jj][1]\n";
die "***ERROR: IPCx type mis-match for IPCx component $::ipcxParts[$ii][0] $::ipcxParts[$ii][1] : $typeComp vs\. $ipcxData[$jj][1] force = $::force_shm_ipc\n";
}
#
......@@ -590,12 +594,18 @@ $ipcxRcvrCnt = 0;
$ipcxTypeIndex = -999;
$::ipcxCommMech = substr($::ipcxParts[$ipcxAdd[$jj][0]][1], 1, 4);
if ($::virtualiop == 1 or $::force_shm_ipc) {
$::ipcxCommMech = "SHMEM";
}
for ($kk = 0; $kk < 4; $kk++) {
if ($::ipcxCommMech eq substr($ipcxType[$kk], 0, 4) ) {
$ipcxTypeIndex = $kk;
}
}
if ($::virtualiop == 1 or $::force_shm_ipc) {
$ipcxTypeIndex = 0;
}
if ($ipcxTypeIndex < 0) {
die "***ERROR: IPCx Communication Mechanism not recognized: $::ipcxCommMech\n";
......
......@@ -174,6 +174,8 @@ sub parseParams {
$::requireIOcnt = $spp[1];
} elsif ($spp[0] eq "virtualIOP") {
$::virtualiop = $spp[1];
} elsif ($spp[0] eq "use_shm_ipc") {
$::force_shm_ipc = $spp[1];
} elsif ($spp[0] eq "adcclock") {
$::adcclock = $spp[1];
} elsif ($spp[0] eq "clock_div") {
......
......@@ -197,7 +197,7 @@ sub createGdsMedm
$medmdata .= ("CDS::medmGen::medmGenTextDyn") -> ($xpos,$ypos,$width,$height,"TIMER",$ecolors{green},"A&16","$site\:FEC-$dcuid\_TIME_ERR");
# Add NO SYNC Alaram Monitor
$xpos = 125; $ypos = 111; $width = 50; $height = 16;
$medmdata .= ("CDS::medmGen::medmGenTextDyn") -> ($xpos,$ypos,$width,$height,"NO SYNC",$ecolors{red},"(A&255) == 0","$site\:FEC-$dcuid\_TIME_ERR");
$medmdata .= ("CDS::medmGen::medmGenTextDyn") -> ($xpos,$ypos,$width,$height,"ExtClk",$ecolors{red},"(A&255) == 0","$site\:FEC-$dcuid\_TIME_ERR");
# Add Uptime
$xpos = 680; $ypos = 46; $width = 100; $height = 21;
......
Software in this directory is used to build the FE computer code.
IOP Kernel Module Software ************************
The RCG supports 2 basic Matlab model configurations:
1) IOP model: Purpose is to provide:
a) FE synchronization to Timing Distribution System (TDS)
b) Read data from ADC modules
c) Write data to DAC modules
d) Provide pointers to digial I/O and real-time IPC (Dolphin) network
2) User Application Models which provide the actual control algorithms
There are various configuration options to both of these model types. The
options are set using the Parameter Block settings in the Matlab file.
Secion I below describes the IOP options.
Section II below describes the User App options.
********************************************************************************
SECTION I: IOP Kernel Module Software ******************************************
********************************************************************************
*** Required C Code Files:
controllerIop.c - Primary infinite control loop; controls I/O and timing
moduleLoad.c - Handles kernel module loading and unloading
......@@ -10,8 +26,9 @@ IOP Kernel Module Software ************************
include/drv/iop_dac_functions - Handles DAC I/O
include/drv/dac_info.c - Provides DAC card status info
include/drv/adc_info.c - Provides ADC card status info
***
REQUIRED Model Parameter Block Entries:
****
The RCG uses model Parameter block entries to obtian compile options.
REQUIRED Model Parameter Block Entries for all IOP configurations:
***
site=IFO_DESIGNATOR eg L1,H1,X2
rate=MODEL_CYCLE_RATE, standard 64K for production systems
......@@ -22,52 +39,119 @@ IOP Kernel Module Software ************************
***
Parameter Block Entries for Specific Use Cases::
***
1) Long Range IOP Configuration ***************************************
1) Standard LIGO Configuration (SLC) **************************************
This is defined as a FE computer that has an I/O chassis (IOC) connected,
via a PCIe or short range fiber optic cable. The IOC contains all of
the following:
a) LIGO timing slave module connected to the LIGO
Timing Distribution System (TDS).
b) Contec1616 binary I/O (BIO) to control the timing slave
c) IRIG-B time code receiver connected to TDS IRIG timing
d) At least one ADC module
e) No more than combined total of ADC/DAC modules
There are a number of compile options for the SLC:
a) pciRfm=1: Used in most LIGO systems, indicates connection
to the Dolphin network for real-time comms between FE
computers.
b) dolphingen=1: Used in conjunctions with pciRfm. By default,
FE code with use Dolphin Gen2 drivers. This option is set
if Dolphin Gen1 is desired.
c) time_master=1: This IOP will send GPS time (seconds) and
cycle count (0-65535). This is used to trigger IOP timing
for FE computers that do not have IOC connected.
WORNING: THERE CAN ONLY BE ONE TIME MASTER ON THE DOLPHIN
NETWORK.
2) Standard configuration EXCEPT no LIGO TDS ******************************
In this configuration, an ADC/DAC clocking signal is provided via a
a non-LIGO TDS ie the clock for I/O modules is provided by some
other method than via a LIGO timing slave. Options here are:
a) A 64K clock is provided to clock the I/O module and a 1PPS sync
signal is provided on the last channel of the first ADC.
No special Parameter block setting is required.
On IOP startup, if it does not find a Contec1616
module to control the timing signal, it will fail over to
trying to sync to a 1PPS signal.
b) A 64K clock is provided without 1PPS sync. This is the configuration
commonly referred to as a Cymac. Any 65536Hz TTL clock can be used.
For this confiuration, set the following Parameter:
1) no_sync=1
WARNING: If there are multiple ADC modules in the system, the IOP
may have issues getting all of them to start on the same
clock cycle. This would be noticed by long IOP cycle times.
An IOP restart may, or may not, correct this.
3) FE computer without an IOC or I/O modules connected. **********************
There are 2 options for running an IOP on a FE withoutI/O modules:
a) As an FE connected to a Dolphin network on a distributed system.
In LIGO production systems, this is used on FE that use IPC
inputs from other FE exclusively in performing their
calculations and only use IPCs to output control signals.
Parameter block entries required for this use case:
1) pciRfm=1
2) time_slave=1
b) As a "virtual" machine for testing on a standalone computer.
In this mode, the IOP will use the CPU time to control its
timing.
Parameter block entries required for this use case:
1) virtualIOP=1
NOTES:
1) ADC input signals will be static. The value for each ADC
card input will equal its channel number eg chan 0 = 0,
chan 1 = 1, etc. Ability to change ADC input values
dynaically is on the TODO list.
2) Any IPCs defined in the IOP model will be set to use
shared memory (SHM) type, regardless of type setting
in the .mdl file. Since there are no I/O cards, this
is the only option.
4) Long Range IOP Configuration ********************************************
When the IO chassis is connected over a long range fiber, such as mid
station PEM:, set the following:
- rate=64K
- clock_div=2
In this configuration, IOP waits for 2 adc samples/chan to begin
station PEM:, set the following in the Parameter block:
1) rate=64K
2) clock_div=2
In this configuration, the IOP waits for 2 adc samples/chan to begin
a processing cycle, instead of the usual one sample. The code
will run thru 2 complete signals everytime it is triggered and
continue to pass ADC data to user models at standard 64K rate.
2) High Speed ADC Configuration ***************************************
will run thru 2 complete cycles everytime it is triggered and
continue to pass ADC data to user models at the standard 64K rate.
5) High Speed ADC Configuration (512KHz Clock) *****************************
WARNING: TESTING OF THIS CONFIGURATION IS NOT COMPLETE
For a specific A+ application, a 1MS/sec ADC is clocked at 512KHz.
The IOP gets triggered every 8 samples, processes data at 512K, and
passes data to user models at the standard 64K rate (no downsample
filtering).
Necessary Parameter Block settings for this configuration.
- rate=512K
- clock_div=8
3) TIME MASTER / TIME SLAVE Configuration *****************************
This configuration provides the capability to connect FE computers
without IO chassis to a distribued system interconnected via a
Dolphine network. In this configuration, time and 64K clock cycle
are sent over the Dolphin IPC network to provide control model
timing in lieu of the usual ADC clocking.
There must be one, and only one, TIME MASTER, which sends the timing
info on the Dolphin network:
Necessary Parameter Block settings for TIME MASTER.
- rate=64K : Time master must have IO chassis and run at 64K
- time_master=1
Necessary Parameter Block settings for TIME SLAVE (FE w/o IOC).
- rate=64K : Time slave IOP must run at 64K
- time_slave=1
4) Non_LIGO Timing System Configuration *****************************
This configuration is designed to support test systems, such as
CYMAC standalone lab test systems, that do not receive their
ADC/DAC clocks from a LIGO timing slave.
Necessary Parameter Block settings for this configuration.
- no_sync=1
1) rate=512K
2) clock_div=8
NOTE: LIGO standard 16bit ADC modules can coexist with the high
speed ADC cards. However, they must still be clocked at the
LIGO standard 64KHz. Therefore, the IOC must be provided
with both a 512KHz clock for fast ADCs and 64K clocks for
standard ADCs.
6) Non-LICO standard clock rate configuration (UNDER DEVELOPMENT) **********
7) Addional Optional IOP Parameter Block Settings **************************
a) optimizeIO=1 : When set, the IOP will not preload the DAC FIFOs with
the usual 2 samples at startup. This can provide for lower phase
delay for 2 clock cycles, or 30 usec at the typical 64K IOP rate.
b) requireIOcnt=1 : When set, IOP will not run unless it finds all of the
I/O cards specified in the control model. This is provided as a
safety factor for code running on production system.s
c) ref_delay=1 : Due to the long transmission delays between LIGO corner
and end station computers, it may be desirable in some cases to
allow extra IPC transmission time. The transmitting model will use
this setting to provide 1 extra code cycle delay for IPC receivers.
d) no_cpu_shutdown=1 : At runtime, code will be assigned to the CPU core
specified in the Matlab model but the core will not be locked ie
code installed as a typical kernel module. This is useful when
testing a model on a computer that does not have the LIGO CDS realtime
patch installed in the kernel.
Virtual Configuration (No I/O and no timing available)
*** Test configuration
User Application Kernel Module Configurations ************************
*********************************************************************************
SECTION II: User Application Kernel Module Configurations ***********************
*********************************************************************************
*** This is the standard production configuration for non-IOP models
controllerApp.c - Primary infinite control loop; controls I/O and timing
moduleLoad.c - Handles kernel module loading and unloading
......@@ -76,5 +160,35 @@ User Application Kernel Module Configurations ************************
drv/app_dac_functions.c - Handles DAC I/O
drv/app_dio_routines.c - Provides DIO card I/O
Following are due for deletion once dependent codes have been cleaned up to no longer use:
- controllerCymac.c -> Simple ifdef change to controllerIop.c ????
****
The RCG uses model Parameter block entries to obtian compile options.
REQUIRED Model Parameter Block Entries for all IOP configurations:
***
site=IFO_DESIGNATOR eg L1,H1,X2
rate=MODEL_CYCLE_RATE, 2K, 4K, 16K, 32K, 64K
dcuid=DCUID, a system unique number for data acquisition
- NOTE: 1 thru 6 and 14,15 are reserved for DAQ and may not be used
adcSlave=1 : Indicates this model is to be compiled as an IOP
host=COMPUTER_HOST_NAME : Name of computer on which this code is to run
***
***
Unlike the IOP, the User App really only has a single run time configuration.
It is compatable with all IOP configurations. However, there are a few
compile options intended for test systems:
1) no_zero_pad=1 : In performing upsampling of DAC outputs to match IOP
rate, the user app code using zero padding in its upsample filtering.
If this option is set, zero padding is disabled.
2) no_cpu_shutdown=1 : At runtime, code will be assigned to the CPU core
specified in the Matlab model but the core will not be locked ie
code installed as a typical kernel module. This is useful when
testing a model on a computer that does not have the LIGO CDS realtime
patch installed in the kernel.
3) use_shm_ipc=1 : Regardless of IPC type definition in the Matlab model,
the RCG will force all IPCs to be defined as SHMEM type. This can be
useful in running a production system model, most of which use PCIe
type IPC, in a standlone system for testing. IPC receivers in
the model still need to find the channels in your IFO.ipc file. A quick
way to to this is:
1) Copy over theproduction system IPC file
2) Use sed, or similar, to change all ipcType=SHMEM
3) Use sed, or similar, to change all ipcHost="Your computer name"
......@@ -65,7 +65,7 @@ int getGpsTime( unsigned int* tsyncSec, unsigned int* tsyncUsec );
// Include C code modules
#include "moduleLoad.c"
#ifdef TIME_SLAVE
#if defined( RUN_WO_IO_MODULES ) || defined( TIME_SLAVE )
#include "mapVirtual.c"
#include <drv/time_slave_io.c>
#else
......@@ -194,6 +194,9 @@ fe_start_controller( void* arg )
#ifdef NO_SYNC
syncSource = SYNC_SRC_NONE;
#endif
#ifdef RUN_WO_IO_MODULES
syncSource = SYNC_SRC_TIMER;
#endif
#ifdef TIME_MASTER
pcieTimer =
......@@ -376,8 +379,7 @@ fe_start_controller( void* arg )
/// \n
/// - --------- DAC timing diags will later check FIFO sizes to verify
/// synchrounous timing.
// #ifndef NO_DAC_PRELOAD
#if !defined( NO_DAC_PRELOAD ) && !defined( TIME_SLAVE )
#ifndef NO_DAC_PRELOAD
status = iop_dac_preload( dacPtr );
#endif
/// - ---- Start the timing clocks\n
......@@ -395,8 +397,7 @@ fe_start_controller( void* arg )
}
break;
case SYNC_SRC_1PPS:
// #ifndef NO_DAC_PRELOAD
#if !defined( NO_DAC_PRELOAD ) && !defined( TIME_SLAVE )
#ifndef NO_DAC_PRELOAD
gsc16ai64Enable( &cdsPciModules );
status = iop_dac_preload( dacPtr );
#endif
......@@ -412,6 +413,9 @@ fe_start_controller( void* arg )
case SYNC_SRC_DOLPHIN:
sync21pps = 1;
break;
case SYNC_SRC_TIMER:
sync21pps = 1;
break;
default:
{
// IRIG-B card not found, so use CPU time to get close to 1PPS on
......@@ -432,6 +436,11 @@ fe_start_controller( void* arg )
#elif TIME_SLAVE
timeSec = sync2master( pcieTimer );
sync21pps = 1;
#elif RUN_WO_IO_MODULES
// printk("Sync to cpu\n");
timeSec = sync2cpuclock( );
// printk("Sync to cpu %old\n",timeSec);
sync21pps = 1;
#else
timeSec = current_time_fe( ) - 1;
#endif
......@@ -457,22 +466,6 @@ fe_start_controller( void* arg )
// *****************************************************************************************
// NORMAL OPERATION -- Wait for ADC data ready
// *****************************************************************************************
#ifndef RFM_DIRECT_READ
/// \> If IOP and RFM DMA selected, block transfer data from GeFanuc RFM
/// cards.
// Used in block transfers of data from GEFANUC RFM
/// - ---- Want to start the DMA ASAP, before ADC data starts coming in.
/// - ---- Note that data only xferred every 4th cycle of IOP, so max
/// data rate on RFM is 16K.
if ( ( cycleNum % 4 ) == 0 )
{
if ( cdsPciModules.pci_rfm[ 0 ] )
vmic5565DMA( &cdsPciModules, 0, ( cycleNum % IPC_BLOCKS ) );
if ( cdsPciModules.pci_rfm[ 1 ] )
vmic5565DMA( &cdsPciModules, 1, ( cycleNum % IPC_BLOCKS ) );
}
#endif
/// \> On 1PPS mark \n
if ( cycleNum == 0 )
{
......@@ -496,10 +489,12 @@ fe_start_controller( void* arg )
cycle_gps_time = timeSec;
}
#ifdef NO_CPU_SHUTDOWN
#ifndef RUN_WO_IO_MODULES
if ( ( cycleNum % 2048 ) == 0 )
{
usleep_range( 1, 3 );
}
#endif
#endif
// Start of ADC Read