From 486a86199a26a94e749fd668b9dda182fac58281 Mon Sep 17 00:00:00 2001
From: controls <controls@x1iscey.dts.ligo-wa.caltech.edu>
Date: Wed, 25 Sep 2019 10:15:48 -0700
Subject: [PATCH] Snapshot of working 1MS/sec code.  Still more to be done.

---
 src/epics/util/feCodeGen.pl         | 46 ++++++++++++++++++++++-------
 src/epics/util/lib/Parameters.pm    |  6 ++++
 src/fe/controllerIop.c              | 16 ++++++++--
 src/fe/moduleLoadCommon.c           |  1 -
 src/include/controller.h            | 15 ++++------
 src/include/drv/iop_adc_functions.c | 33 +++++++--------------
 6 files changed, 71 insertions(+), 46 deletions(-)

diff --git a/src/epics/util/feCodeGen.pl b/src/epics/util/feCodeGen.pl
index 4c1eb2218..8289b8b7b 100755
--- a/src/epics/util/feCodeGen.pl
+++ b/src/epics/util/feCodeGen.pl
@@ -161,6 +161,9 @@ $remoteGpsPart = 0;
 $remoteGPS = 0;
 $daq2dc = 0;
 $requireIOcnt = 0;
+$adcclock = 64;
+$adcrate = 64;
+$adc_std_rate = 64;
 
 # Normally, ARGV !> 2, so the following are not invoked in a standard make
 # This is legacy.
@@ -212,13 +215,14 @@ if (@ARGV > 4) {
 	} elsif ($param_speed eq "256K") {
 		$rate = 4;
 	} elsif ($param_speed eq "512K") {
-		$rate = 2;
+		$rate = 2; 
 	} elsif ($param_speed eq "1024K") {
 		$rate = 1;
 	} else  { die "Invalid speed $param_speed specified\n"; }
 }
 
 
+
 # Load model name without .mdl extension.
 $skeleton = $ARGV[1];
 
@@ -355,6 +359,11 @@ die unless CDS::Parser::sortDacs();
 
 close(IN);
 
+if(($adcMaster == 1) and ($adcrate > $adcclock)) 
+{
+	die "Error:\nModel rate $adcrate > ADC clock $adcclock\nFix adcclock in Param Block\n*****\n";
+}
+
 #//	
 #// Model now consists of top level parts and single level subsystem(s). <em>Parser3.pm</em> has taken care of all part
 #// removals/connections for lower level subsystems.\n
@@ -1204,27 +1213,29 @@ print EPICS "OUTVARIABLE FEC\_$dcuId\_TP_CNT epicsOutput.tpCnt int ao 0\n";
 
 print OUTH "\tint cpuMeter;\n";
 $frate = $rate;
-if($frate == 15)
+if($frate <= 15)
 {
 	$brate =  13;
+	$mrate = 15;
 } else {
 	$frate =  $rate * .85;
 	$brate = $frate;
+	$mrate = $rate;
 }
 $cpuM = $site . ":FEC-" . $dcuId . "_CPU_METER";
-print EPICS "OUTVARIABLE FEC\_$dcuId\_CPU_METER epicsOutput.cpuMeter int ao 0 field(HOPR,\"$rate\") field(LOPR,\"0\") field(HIHI,\"$rate\") field(HHSV,\"MAJOR\") field(HIGH,\"$brate\") field(HSV,\"MINOR\") field(EGU,\"usec\")\n";
+print EPICS "OUTVARIABLE FEC\_$dcuId\_CPU_METER epicsOutput.cpuMeter int ao 0 field(HOPR,\"$mrate\") field(LOPR,\"0\") field(HIHI,\"$mrate\") field(HHSV,\"MAJOR\") field(HIGH,\"$brate\") field(HSV,\"MINOR\") field(EGU,\"usec\")\n";
 
 print OUTH "\tint cpuMeterMax;\n";
-print EPICS "OUTVARIABLE FEC\_$dcuId\_CPU_METER_MAX epicsOutput.cpuMeterMax int ao 0 field(HOPR,\"$rate\") field(LOPR,\"0\") field(HIHI,\"$rate\") field(HHSV,\"MAJOR\") field(HIGH,\"$brate\") field(EGU,\"usec\") field(HSV,\"MINOR\")\n";
+print EPICS "OUTVARIABLE FEC\_$dcuId\_CPU_METER_MAX epicsOutput.cpuMeterMax int ao 0 field(HOPR,\"$mrate\") field(LOPR,\"0\") field(HIHI,\"$mrate\") field(HHSV,\"MAJOR\") field(HIGH,\"$brate\") field(EGU,\"usec\") field(HSV,\"MINOR\")\n";
 
 print OUTH "\tint adcWaitTime;\n";
-print EPICS "OUTVARIABLE FEC\_$dcuId\_ADC_WAIT epicsOutput.adcWaitTime int ao 0 field(HOPR,\"$rate\") field(EGU,\"usec\") field(LOPR,\"0\")\n";
+print EPICS "OUTVARIABLE FEC\_$dcuId\_ADC_WAIT epicsOutput.adcWaitTime int ao 0 field(HOPR,\"$mrate\") field(EGU,\"usec\") field(LOPR,\"0\")\n";
 
 print OUTH "\tint adcWaitMin;\n";
-print EPICS "OUTVARIABLE FEC\_$dcuId\_ADC_WAIT_MIN epicsOutput.adcWaitMin int ao 0 field(HOPR,\"$rate\") field(EGU,\"usec\") field(LOPR,\"0\")\n";
+print EPICS "OUTVARIABLE FEC\_$dcuId\_ADC_WAIT_MIN epicsOutput.adcWaitMin int ao 0 field(HOPR,\"$mrate\") field(EGU,\"usec\") field(LOPR,\"0\")\n";
 
 print OUTH "\tint adcWaitMax;\n";
-print EPICS "OUTVARIABLE FEC\_$dcuId\_ADC_WAIT_MAX epicsOutput.adcWaitMax int ao 0 field(HOPR,\"$rate\") field(EGU,\"usec\") field(LOPR,\"0\")\n";
+print EPICS "OUTVARIABLE FEC\_$dcuId\_ADC_WAIT_MAX epicsOutput.adcWaitMax int ao 0 field(HOPR,\"$mrate\") field(EGU,\"usec\") field(LOPR,\"0\")\n";
 
 print OUTH "\tint timeErr;\n";
 print EPICS "OUTVARIABLE FEC\_$dcuId\_TIME_ERR epicsOutput.timeErr int ao 0\n";
@@ -1556,8 +1567,8 @@ for($ii=0;$ii<$partCnt;$ii++)
 	}
 	#//		- Add GDS info.
     $gdsrate = get_freq();
-    if($gdsrate > 65536) {
-        $gdsrate = 65536;
+    if($gdsrate > 524768) {
+        $gdsrate = 524768;
     }
 	print EPICS "gds_config $gdsXstart $gdsTstart 1250 1250 $gdsNodeId $site $gdsrate $dcuId $ifoid\n";
 	print EPICS "\n\n";
@@ -1573,30 +1584,39 @@ for($ii=0;$ii<$partCnt;$ii++)
 
 #ifdef SERVO1024K
 	#define FE_RATE	1048576
+	#define IPC_RATE	65536
 #endif
 #ifdef SERVO512K
 	#define FE_RATE	524288
+	#define IPC_RATE	65536
 #endif
 #ifdef SERVO256K
 	#define FE_RATE	262144
+	#define IPC_RATE	65536
 #endif
 #ifdef SERVO128K
 	#define FE_RATE	131072
+	#define IPC_RATE	65536
 #endif
 #ifdef SERVO64K
 	#define FE_RATE	65536
+	#define IPC_RATE	FE_RATE
 #endif
 #ifdef SERVO32K
 	#define FE_RATE	32768
+	#define IPC_RATE	FE_RATE
 #endif
 #ifdef SERVO16K
 	#define FE_RATE	16384
+	#define IPC_RATE	FE_RATE
 #endif
 #ifdef SERVO4K
 	#define FE_RATE	4096
+	#define IPC_RATE	FE_RATE
 #endif
 #ifdef SERVO2K
 	#define FE_RATE	2048
+	#define IPC_RATE	FE_RATE
 #endif
 
 
@@ -2495,8 +2515,6 @@ print OUTM "# CPU-Shutdown Real Time Linux\n";
 print OUTM "KBUILD_EXTRA_SYMBOLS=$rcg_src_dir/src/drv/ExtraSymbols.symvers\n";
 print OUTM "ALL \+= user_mmap \$(TARGET_RTL)\n";
 print OUTM "EXTRA_CFLAGS += -O -w -I../../include\n";
-print OUTM "EXTRA_CFLAGS += -I/opt/gm/include\n";
-print OUTM "EXTRA_CFLAGS += -I/opt/mx/include\n";
 
 if($rate == 480) { print OUTM "EXTRA_CFLAGS += -DSERVO2K\n"; }
 elsif($rate == 240) { print OUTM "EXTRA_CFLAGS += -DSERVO4K\n"; }
@@ -2578,6 +2596,12 @@ if ($adcMaster > -1) {
   if($diagTest > -1) {
   print OUTM "EXTRA_CFLAGS += -DDIAG_TEST\n";
   }
+  if($adcclock > $adc_std_clock) {
+  	$undersample = $adcclock/$adc_std_rate;
+  } else {
+  	$undersample = $adcclock/$adcrate;
+  }
+  print OUTM "EXTRA_CFLAGS += -DUNDERSAMPLE=$undersample\n";
   if($dacWdOverride > -1) {
   print OUTM "EXTRA_CFLAGS += -DDAC_WD_OVERRIDE\n";
   }
diff --git a/src/epics/util/lib/Parameters.pm b/src/epics/util/lib/Parameters.pm
index 844133437..77be6eb2b 100644
--- a/src/epics/util/lib/Parameters.pm
+++ b/src/epics/util/lib/Parameters.pm
@@ -69,12 +69,16 @@ sub parseParams {
                 			$::rate = 15;
         			} elsif ($param_speed eq "128K") {
                 			$::rate = 8;
+                			$::adcrate = 128;
         			} elsif ($param_speed eq "256K") {
                 			$::rate = 4;
+                			$::adcrate = 256;
         			} elsif ($param_speed eq "512K") {
                 			$::rate = 2;
+                			$::adcrate = 512;
         			} elsif ($param_speed eq "1024K") {
                 			$::rate = 1;
+                			$::adcrate = 1024;
         			} else  { die "Invalid speed $param_speed specified\n"; }
 
 			} elsif ($spp[0] eq "dcuid") {
@@ -164,6 +168,8 @@ sub parseParams {
 				$::requireIOcnt = $spp[1];
 			} elsif ($spp[0] eq "virtualIOP") { 
 				$::virtualiop = $spp[1];
+			} elsif ($spp[0] eq "adcclock") { 
+				$::adcclock = $spp[1];
 			} elsif ($spp[0] eq "optimizeIO") { 
 				$::optimizeIO = $spp[1];
 			} elsif ($spp[0] eq "no_zero_pad") { 
diff --git a/src/fe/controllerIop.c b/src/fe/controllerIop.c
index 42967890e..7d2612636 100644
--- a/src/fe/controllerIop.c
+++ b/src/fe/controllerIop.c
@@ -170,6 +170,10 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
   if(cdsPciModules.cDio1616lCount) syncSource = SYNC_SRC_TDS;
   else syncSource = SYNC_SRC_1PPS;
 
+#ifdef NO_SYNC
+  syncSource = SYNC_SRC_NONE;
+#endif
+
 
 #ifdef TIME_MASTER
   pcieTimer = (TIMING_SIGNAL *) ((volatile char *)(cdsPciModules.dolphinWrite[0]) + IPC_PCIE_TIME_OFFSET);
@@ -330,18 +334,25 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
       // This has to be done sequentially, one at a time.
       // status = sync_adc_2_1pps();
       sync21pps = 1;
+      gsc16ai64Enable(&cdsPciModules);
+      gsc18ai32Enable(&cdsPciModules);
+      break;
+    case SYNC_SRC_NONE:
+      gsc16ai64Enable(&cdsPciModules);
       gsc18ai32Enable(&cdsPciModules);
+      sync21pps = 1;
       break;
     default: {
       // IRIG-B card not found, so use CPU time to get close to 1PPS on startup
       // Pause until this second ends
+      gsc16ai64Enable(&cdsPciModules);
       gsc18ai32Enable(&cdsPciModules);
       sync21pps = 1;
       break;
     }
   }
 
-    for(jj=0;jj<cdsPciModules.adcCount;jj++) gsc18ai32DmaEnable(jj);
+//     for(jj=0;jj<cdsPciModules.adcCount;jj++) gsc18ai32DmaEnable(jj);
   pLocalEpics->epicsOutput.fe_status = NORMAL_RUN;
 
   onePpsTime = cycleNum;
@@ -674,7 +685,8 @@ for(ploop=0;ploop<UNDERSAMPLE;ploop++)
 // *****************************************************************
 #ifndef NO_DAQ
 		
-  if(ploop == 0) {
+  // if(ploop == 0) {
+  if((ploop % 1)== 0) {
     // Call daqLib
     pLocalEpics->epicsOutput.daqByteCnt = 
     daqWrite(1,dcuId,daq,DAQ_RATE,testpoint,dspPtr[0],0,(int *)(pLocalEpics->epicsOutput.gdsMon),xExc,pEpicsDaq);
diff --git a/src/fe/moduleLoadCommon.c b/src/fe/moduleLoadCommon.c
index de0a3fc8c..dba328a87 100644
--- a/src/fe/moduleLoadCommon.c
+++ b/src/fe/moduleLoadCommon.c
@@ -4,7 +4,6 @@
 void print_io_info(CDS_HARDWARE *cdsp) {
   int ii,jj,kk;
   jj = 0;
-	printf("THIS IS A TEST \n");
 #ifndef USER_SPACE
 	printf("" SYSTEM_NAME_STRING_LOWER ":startup time is %ld\n", current_time_fe());
 	printf("" SYSTEM_NAME_STRING_LOWER ":cpu clock %u\n",cpu_khz);
diff --git a/src/include/controller.h b/src/include/controller.h
index 56cfe1548..fd1c97807 100644
--- a/src/include/controller.h
+++ b/src/include/controller.h
@@ -97,34 +97,32 @@ char fp [64*1024];
 #ifdef SERVO1024K
     #define CYCLE_PER_MINUTE        (8*7864320)
     #define DAQ_CYCLE_CHANGE        (32*8000)
-    #define END_OF_DAQ_BLOCK        65535
-	#define DAQ_RATE	(DAQ_16K_SAMPLE_SIZE*4)
+    #define END_OF_DAQ_BLOCK        524287
+	#define DAQ_RATE	(DAQ_16K_SAMPLE_SIZE*32)
 	#define NET_SEND_WAIT		    (32*81920)
     #define CYCLE_TIME_ALRM         15
 	#define CYCLE_TIME_ALRM_HI	    25
 	#define CYCLE_TIME_ALRM_LO	    10
 	#define EPICS_128_SYNC		    2048
 	#define DAC_PRELOAD_CNT		    0
-    #define UNDERSAMPLE             16
 #endif
 #ifdef SERVO512K
     #define CYCLE_PER_MINUTE        (4*7864320)
     #define DAQ_CYCLE_CHANGE        (32*8000)
-    #define END_OF_DAQ_BLOCK        65535
-	#define DAQ_RATE	(DAQ_16K_SAMPLE_SIZE*4)
+    #define END_OF_DAQ_BLOCK        524287
+	#define DAQ_RATE	(DAQ_16K_SAMPLE_SIZE*32)
 	#define NET_SEND_WAIT		    (32*81920)
     #define CYCLE_TIME_ALRM         15
 	#define CYCLE_TIME_ALRM_HI	    25
 	#define CYCLE_TIME_ALRM_LO	    10
 	#define EPICS_128_SYNC		    2048
 	#define DAC_PRELOAD_CNT		    0
-    #define UNDERSAMPLE             8
 #endif
 #ifdef SERVO256K
         #define CYCLE_PER_MINUTE        (2*7864320)
         #define DAQ_CYCLE_CHANGE        (2*8000)
         #define END_OF_DAQ_BLOCK        (2*8191)
-        #define DAQ_RATE                (2*8192)
+	#define DAQ_RATE	(DAQ_16K_SAMPLE_SIZE*16)
         #define NET_SEND_WAIT           (2*655360)
         #define CYCLE_TIME_ALRM         4
 	#define CYCLE_TIME_ALRM_HI	5
@@ -136,7 +134,7 @@ char fp [64*1024];
         #define CYCLE_PER_MINUTE        7864320
         #define DAQ_CYCLE_CHANGE        8000
         #define END_OF_DAQ_BLOCK        8191
-        #define DAQ_RATE                8192
+	#define DAQ_RATE	(DAQ_16K_SAMPLE_SIZE*8)
         #define NET_SEND_WAIT           655360
         #define CYCLE_TIME_ALRM         7
 	#define EPICS_128_SYNC		1024
@@ -152,7 +150,6 @@ char fp [64*1024];
 	#define CYCLE_TIME_ALRM_HI	25
 	#define CYCLE_TIME_ALRM_LO	10
 	#define EPICS_128_SYNC		512
-    #define UNDERSAMPLE         1
 #ifdef ADC_SLAVE
 	#define DAC_PRELOAD_CNT		1
 #else
diff --git a/src/include/drv/iop_adc_functions.c b/src/include/drv/iop_adc_functions.c
index 1dd015a33..79201ee03 100644
--- a/src/include/drv/iop_adc_functions.c
+++ b/src/include/drv/iop_adc_functions.c
@@ -151,7 +151,7 @@ inline int iop_adc_read (adcInfo_t *adcinfo,int cpuClk[])
         if (cdsPciModules.adcType[card] == GSC_18AI32SSC1M)  packedData += GSAF_8_OFFSET;
         else packedData += 31;
 		
-	cpuClk[CPU_TIME_RDY_ADC] = rdtsc_ordered();
+	    cpuClk[CPU_TIME_RDY_ADC] = rdtsc_ordered();
         do {
             /// - ---- Need to delay if not ready as constant banging of the input register
             /// will slow down the ADC DMA.
@@ -251,7 +251,7 @@ inline int iop_adc_read (adcInfo_t *adcinfo,int cpuClk[])
         {
         for(chan=0;chan<num_outs;chan++)
         {
-        // adcData is the integer representation of the ADC data
+            // adcData is the integer representation of the ADC data
             adcinfo->adcData[card][chan] = (*packedData & mask);
             adcinfo->adcData[card][chan]  -= offset;
 #ifdef DEC_TEST
@@ -265,7 +265,7 @@ inline int iop_adc_read (adcInfo_t *adcinfo,int cpuClk[])
             dWord[card][chan][kk] = adcinfo->adcData[card][chan];
             /// - ----  Load ADC value into ipc memory buffer
             ioMemData->iodata[card][ioMemCntr].data[chan] = adcinfo->adcData[card][chan];
-        /// - ---- Check for ADC overflows
+            /// - ---- Check for ADC overflows
             if((adcinfo->adcData[card][chan] > limit) || (adcinfo->adcData[card][chan] < -limit))
             {
                 adcinfo->overflowAdc[card][chan] ++;
@@ -276,28 +276,13 @@ inline int iop_adc_read (adcInfo_t *adcinfo,int cpuClk[])
             }
             packedData ++;
         }
+        }
 
-        /// - ---- Write GPS time and cycle count as indicator to slave that adc data is ready
+       	/// - ---- Write GPS time and cycle count as indicator to slave that adc data is ready
         ioMemData->gpsSecond = timeSec;
         ioMemData->iodata[card][ioMemCntr].timeSec = timeSec;
-        ioMemData->iodata[card][ioMemCntr].cycle = cycleNum + kk;
-        ioMemCntr ++;
+        ioMemData->iodata[card][ioMemCntr].cycle = cycleNum;
 
-#if 0
-        /// - ---- Check for ADC overflows
-        for(chan=0;chan<num_outs;chan++)
-        {
-            if((adcinfo->adcData[card][chan] > limit) || (adcinfo->adcData[card][chan] < -limit))
-            {
-                adcinfo->overflowAdc[card][chan] ++;
-                pLocalEpics->epicsOutput.overflowAdcAcc[card][chan] ++;
-                overflowAcc ++;
-                adcinfo->adcOF[card] = 1;
-                odcStateWord |= ODC_ADC_OVF;
-            }
-        }
-#endif
-        }
 
         /// - ---- Clear out last ADC data read for test on next cycle
         packedData = (int *)cdsPciModules.pci_adc[card];
@@ -305,9 +290,11 @@ inline int iop_adc_read (adcInfo_t *adcinfo,int cpuClk[])
 
         if (cdsPciModules.adcType[card] == GSC_18AI32SSC1M) packedData += GSAF_8_OFFSET;
         else packedData += GSAI_CHAN_COUNT_M1;
-
+        // Set dummy value to last channel
         *packedData = DUMMY_ADC_VAL;
-         gsc18ai32DmaEnable(card);
+        // Enable the ADC Demand DMA for next read
+        if (cdsPciModules.adcType[card] == GSC_18AI32SSC1M) gsc18ai32DmaEnable(card);
+        else gsc16ai64DmaEnable(card);
 
 #ifdef DIAG_TEST
 // For DIAGS ONLY !!!!!!!!
-- 
GitLab