diff --git a/src/drv/param.c b/src/drv/param.c
index c55e1d0099af14ad995b1efe1dd3e943da668b1f..6635158b6c855742c920ae8cae630ab93d9133ad 100644
--- a/src/drv/param.c
+++ b/src/drv/param.c
@@ -283,7 +283,7 @@ parseConfigFile(char *fname, unsigned long *crc,
           }
 	  return 0; 
 	}
-	if (current.datarate < 16 || current.datarate > (256*1024)) {
+	if (current.datarate < 16 || current.datarate > (512*1024)) {
 	  system_log(1, "data rate out of range in %s:%d", fname, linenum);
 	  fclose(fp);
           if (afp) {
diff --git a/src/epics/util/feCodeGen.pl b/src/epics/util/feCodeGen.pl
index e6a36455233217e567531f54bcd9a851e04b2123..4c1eb2218bc02ef7e7ee2c3a5f1ff7d0c713c6ee 100755
--- a/src/epics/util/feCodeGen.pl
+++ b/src/epics/util/feCodeGen.pl
@@ -211,6 +211,10 @@ if (@ARGV > 4) {
 		$rate = 15;
 	} elsif ($param_speed eq "256K") {
 		$rate = 4;
+	} elsif ($param_speed eq "512K") {
+		$rate = 2;
+	} elsif ($param_speed eq "1024K") {
+		$rate = 1;
 	} else  { die "Invalid speed $param_speed specified\n"; }
 }
 
@@ -1551,7 +1555,11 @@ for($ii=0;$ii<$partCnt;$ii++)
 		print EPICS "sdf_flavor_ca\n";
 	}
 	#//		- Add GDS info.
-	print EPICS "gds_config $gdsXstart $gdsTstart 1250 1250 $gdsNodeId $site " . get_freq() . " $dcuId $ifoid\n";
+    $gdsrate = get_freq();
+    if($gdsrate > 65536) {
+        $gdsrate = 65536;
+    }
+	print EPICS "gds_config $gdsXstart $gdsTstart 1250 1250 $gdsNodeId $site $gdsrate $dcuId $ifoid\n";
 	print EPICS "\n\n";
 	close EPICS;
 
@@ -1563,6 +1571,12 @@ for($ii=0;$ii<$partCnt;$ii++)
 // ******* DO NOT HAND EDIT ************************
 #include "fe.h"
 
+#ifdef SERVO1024K
+	#define FE_RATE	1048576
+#endif
+#ifdef SERVO512K
+	#define FE_RATE	524288
+#endif
 #ifdef SERVO256K
 	#define FE_RATE	262144
 #endif
@@ -2262,6 +2276,10 @@ sub get_freq {
 		return 64*1024;
 	} elsif ($rate == 4) {
 		return 256*1024;
+	} elsif ($rate == 2) {
+		return 512*1024;
+	} elsif ($rate == 1) {
+		return 1024*1024;
 	}
 }
 
@@ -2487,6 +2505,9 @@ elsif($rate == 30) { print OUTM "EXTRA_CFLAGS += -DSERVO32K\n"; }
 elsif($rate == 15) { print OUTM "EXTRA_CFLAGS += -DSERVO64K\n"; }
 elsif($rate == 7) { print OUTM "EXTRA_CFLAGS += -DSERVO128K\n"; }
 elsif($rate == 4) { print OUTM "EXTRA_CFLAGS += -DSERVO256K\n"; }
+elsif($rate == 2) { print OUTM "EXTRA_CFLAGS += -DSERVO512K\n"; }
+elsif($rate == 1) { print OUTM "EXTRA_CFLAGS += -DSERVO1024K\n"; }
+
 
 print OUTM "EXTRA_CFLAGS += -D";
 print OUTM "\U$skeleton";
@@ -2707,6 +2728,8 @@ elsif($rate == 30) { print OUTM "CFLAGS += -DSERVO32K\n"; }
 elsif($rate == 15) { print OUTM "CFLAGS += -DSERVO64K\n"; }
 elsif($rate == 7) { print OUTM "CFLAGS += -DSERVO128K\n"; }
 elsif($rate == 4) { print OUTM "CFLAGS += -DSERVO256K\n"; }
+elsif($rate == 2) { print OUTM "CFLAGS += -DSERVO512K\n"; }
+elsif($rate == 1) { print OUTM "CFLAGS += -DSERVO1024K\n"; }
 
 print OUTM "CFLAGS += -D";
 print OUTM "\U$skeleton";
diff --git a/src/epics/util/iniChk.pl b/src/epics/util/iniChk.pl
index b2c86d49b3809dde93eb7fdf6e6ecf061c150061..fdb1840bec26604ddcf623fa256bae642c3dc9f7 100755
--- a/src/epics/util/iniChk.pl
+++ b/src/epics/util/iniChk.pl
@@ -179,7 +179,7 @@ sub processDataRate  {
    my $correctDataRate = -1;
    my $dataRateHelp = 16;
 
-   for (my $i = 0; $i < 13; $i++)  {
+   for (my $i = 0; $i < 24; $i++)  {
       if ($rate == $dataRateHelp)  {
          $correctDataRate = $i;
          last;
@@ -269,7 +269,7 @@ foreach $value (@inData)  {
 #           $acquireCount[$defaultAcquireValue]++;
 #        }
 
-         for (my $i = 0; $i < 9; $i++)  {
+         for (my $i = 0; $i < 20; $i++)  {
             $rateCount[$i] = 0;
          }
       }
@@ -317,7 +317,7 @@ print "\nTotal count of \'acquire={0,1,3}\' is $acquireTotal\n";
 $dataRateHelp = 16;
 $totalByteCount = 0;
 
-for ($i = 0; $i < 13; $i++)  {
+for ($i = 0; $i < 17; $i++)  {
    $totalBytes = $dataRateHelp * $rateCount[$i];
    print "\nCounted $rateCount[$i] entries of datarate=$dataRateHelp \tfor a total of $totalBytes";
 
@@ -332,7 +332,7 @@ print "\n\nTotal data rate is $totalByteCount bytes - ";
 #  Check that the total datarate is 4M bytes or less.
 #  Print a warning message if it is not.
 #
-if ($totalByteCount <= 4194304)  {
+if ($totalByteCount <= 8194304)  {
    print "OK\n";
 }
 else  {
diff --git a/src/epics/util/lib/Adc.pm b/src/epics/util/lib/Adc.pm
index a7b7a270b5b7aa819b1e0e1ef2bca6c9e26e9790..bf956ae25e14c23a60f9fecd582d38325fe86d02 100644
--- a/src/epics/util/lib/Adc.pm
+++ b/src/epics/util/lib/Adc.pm
@@ -13,7 +13,7 @@ require "lib/medmGen.pm";
 # ADC cards we support
 %board_types = (
 	GSC_16AI64SSA => 1, # Slow General Standards board
-        GSC_18AISS6C => 1 # 18-bit 6 channel General Standards board
+        GSC_18AI32SSC1M => 1 # 18-bit 8/16/24/32 channel General Standards board
 );
 
 # default board type (if none specified with type=<type> in block Description)
diff --git a/src/epics/util/lib/Parameters.pm b/src/epics/util/lib/Parameters.pm
index 4487c012debf930b476911ace1689195df983aa0..8441334378ae427bc120bb9a4096f17a8ce58344 100644
--- a/src/epics/util/lib/Parameters.pm
+++ b/src/epics/util/lib/Parameters.pm
@@ -71,6 +71,10 @@ sub parseParams {
                 			$::rate = 8;
         			} elsif ($param_speed eq "256K") {
                 			$::rate = 4;
+        			} elsif ($param_speed eq "512K") {
+                			$::rate = 2;
+        			} elsif ($param_speed eq "1024K") {
+                			$::rate = 1;
         			} else  { die "Invalid speed $param_speed specified\n"; }
 
 			} elsif ($spp[0] eq "dcuid") {
diff --git a/src/fe/commData3.c b/src/fe/commData3.c
index d7a65edd272a2ae20973dfc16a4d7656c976936c..3f4ea97260f9dc09721245f8311602d6cb9a1e46 100644
--- a/src/fe/commData3.c
+++ b/src/fe/commData3.c
@@ -43,12 +43,12 @@ int ii;
 unsigned long ipcMemOffset;
 
 
-printf("size of data block = 0x%x\n", sizeof(CDS_IPC_COMMS));
-printf("Dolphin num = %d \n",cdsPciModules.dolphinCount);
-printf("\tLocal at 0x%x and 0x%x \n",cdsPciModules.dolphinRead[0],cdsPciModules.dolphinWrite[0]);
-printf("\tRFM   at 0x%x and 0x%x \n",cdsPciModules.dolphinRead[1],cdsPciModules.dolphinWrite[1]);
+// printf("size of data block = 0x%x\n", sizeof(CDS_IPC_COMMS));
+// printf("Dolphin num = %d \n",cdsPciModules.dolphinCount);
+// printf("\tLocal at 0x%x and 0x%x \n",cdsPciModules.dolphinRead[0],cdsPciModules.dolphinWrite[0]);
+// printf("\tRFM   at 0x%x and 0x%x \n",cdsPciModules.dolphinRead[1],cdsPciModules.dolphinWrite[1]);
 #ifdef RFM_DELAY
-printf("Model compiled with RFM DELAY !!\n");
+// printf("Model compiled with RFM DELAY !!\n");
 #endif
   for(ii=0;ii<connects;ii++)
   {
@@ -157,9 +157,9 @@ printf("Model compiled with RFM DELAY !!\n");
   for(ii=0;ii<connects;ii++)
   {
 	if(ipcInfo[ii].mode == ISND && ipcInfo[ii].netType != ISHME) {
-        printf("IPC Name = %s \t%d\t%d\t%lx\t%lx\n",ipcInfo[ii].name,ipcInfo[ii].netType,ipcInfo[ii].ipcNum,
-		(unsigned long)&ipcInfo[ii].pIpcDataWrite[0]->dBlock[0][ipcInfo[ii].ipcNum].data,
-		(unsigned long)&ipcInfo[ii].pIpcDataWrite[0]->dBlock[63][ipcInfo[ii].ipcNum].timestamp);
+        // printf("IPC Name = %s \t%d\t%d\t%lx\t%lx\n",ipcInfo[ii].name,ipcInfo[ii].netType,ipcInfo[ii].ipcNum,
+		// (unsigned long)&ipcInfo[ii].pIpcDataWrite[0]->dBlock[0][ipcInfo[ii].ipcNum].data,
+		// (unsigned long)&ipcInfo[ii].pIpcDataWrite[0]->dBlock[63][ipcInfo[ii].ipcNum].timestamp);
 	}
   }
 }
@@ -190,13 +190,13 @@ INLINE void commData3Send(int connects,  	 	// Total number of IPC connections i
 #ifdef RFM_DELAY
 // Need to write ahead one extra block
   int mycycle = (cycle + 1);
-  sendBlock = ((mycycle + 1) * (IPC_MAX_RATE / FE_RATE)) % IPC_BLOCKS;
+  sendBlock = ((mycycle + 1) * (IPC_MAX_RATE / IPC_RATE)) % IPC_BLOCKS;
   dataCycle = ((mycycle + 1) * ipcInfo[0].sendCycle) % IPC_MAX_RATE;
   if(dataCycle == 0 || dataCycle == ipcInfo[0].sendCycle) syncWord = timeSec + 1;
   else syncWord = timeSec;
   syncWord = (syncWord << 32) + dataCycle;
 #else
-  sendBlock = ((cycle + 1) * (IPC_MAX_RATE / FE_RATE)) % IPC_BLOCKS;
+  sendBlock = ((cycle + 1) * (IPC_MAX_RATE / IPC_RATE)) % IPC_BLOCKS;
 // Calculate the SYNC word to be sent with all data.
 // Determine the cycle count to be sent with the data
   dataCycle = ((cycle + 1) * ipcInfo[0].sendCycle) % IPC_MAX_RATE;
@@ -241,7 +241,7 @@ INLINE void commData3Send(int connects,  	 	// Total number of IPC connections i
 #ifdef RFM_DELAY
 // We don't want to delay SHMEM or PCIe writes, so calc block as usual,
 // so need to recalc send block and syncWord.
-  sendBlock = ((cycle + 1) * (IPC_MAX_RATE / FE_RATE)) % IPC_BLOCKS;
+  sendBlock = ((cycle + 1) * (IPC_MAX_RATE / IPC_RATE)) % IPC_BLOCKS;
 // Calculate the SYNC word to be sent with all data.
 // Determine the cycle count to be sent with the data
   dataCycle = ((cycle + 1) * ipcInfo[0].sendCycle) % IPC_MAX_RATE;
@@ -304,7 +304,7 @@ double tmp;			// Temp location for data for checking NaN
 // static unsigned long nskipped = 0;	// number of skipped error messages (couldn't print that fast)
 
   // Determine which block to read, based on present code cycle
-  rcvBlock = ((cycle) * (IPC_MAX_RATE / FE_RATE)) % IPC_BLOCKS;
+  rcvBlock = ((cycle) * (IPC_MAX_RATE / IPC_RATE)) % IPC_BLOCKS;
   for(ii=0;ii<connects;ii++)
   {
         if(ipcInfo[ii].mode == IRCV) // Zero = Rcv and One = Send
diff --git a/src/fe/controllerIop.c b/src/fe/controllerIop.c
index bbabc84bfdcdc12a9289c80a2e1cafc4d478317c..42967890e419c408c3024465a5d854edc090a8b8 100644
--- a/src/fe/controllerIop.c
+++ b/src/fe/controllerIop.c
@@ -49,7 +49,7 @@ duotone_diag_t dt_diag;
 int adcCycleNum = 0;
 // Variables for setting IOP->APP I/O
 int ioClockDac = DAC_PRELOAD_CNT;
-int ioMemCntr = 0;
+// int ioMemCntr = 0;
 int ioMemCntrDac = DAC_PRELOAD_CNT;
 // DAC variable
 int dacEnable = 0;
@@ -119,13 +119,17 @@ void *fe_start_iop(void *arg)
   float duotoneTimeDac;
   float duotoneTime;
 
+  int ploop=1;
+  double adcval[MAX_ADC_MODULES][MAX_ADC_CHN_PER_MOD];
+  
+
 
 
 /// **********************************************************************************************\n
 /// Start Initialization Process \n
 /// **********************************************************************************************\n
 
-  /// \> Flush L1 cache
+/// \> Flush L1 cache
   memset (fp, 0, 64*1024);
   memset (fp, 1, 64*1024);
   clflush_cache_range ((void *)fp, 64*1024);
@@ -255,7 +259,7 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
   vmeDone = 0;
 
   /// \> Call user application software initialization routine.
-  iopDacEnable = feCode(cycleNum,dWord,dacOut,dspPtr[0],&dspCoeff[0], (struct CDS_EPICS *)pLocalEpics,1);
+  iopDacEnable = feCode(cycleNum,adcval,dacOut,dspPtr[0],&dspCoeff[0], (struct CDS_EPICS *)pLocalEpics,1);
 
   // Initialize timing info variables
   initializeTimingDiags(&timeinfo);
@@ -289,7 +293,8 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
       udelay(MAX_UDELAY);
       udelay(MAX_UDELAY);
       /// - ---- Arm ADC modules
-      gsc16ai64Enable(cdsPciModules.adcCount);
+      gsc16ai64Enable(&cdsPciModules);
+      gsc18ai32Enable(&cdsPciModules);
       /// - ----  Arm DAC outputs
       gsc18ao8Enable(&cdsPciModules);
       gsc20ao8Enable(&cdsPciModules);
@@ -318,19 +323,25 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
       break;
     case SYNC_SRC_1PPS:
 #ifndef NO_DAC_PRELOAD
+      gsc16ai64Enable(&cdsPciModules);
       status = iop_dac_preload(dacPtr);
 #endif
       // Arm ADC modules
       // This has to be done sequentially, one at a time.
-      status = sync_adc_2_1pps();
+      // status = sync_adc_2_1pps();
+      sync21pps = 1;
+      gsc18ai32Enable(&cdsPciModules);
       break;
     default: {
       // IRIG-B card not found, so use CPU time to get close to 1PPS on startup
       // Pause until this second ends
+      gsc18ai32Enable(&cdsPciModules);
+      sync21pps = 1;
       break;
     }
   }
 
+    for(jj=0;jj<cdsPciModules.adcCount;jj++) gsc18ai32DmaEnable(jj);
   pLocalEpics->epicsOutput.fe_status = NORMAL_RUN;
 
   onePpsTime = cycleNum;
@@ -352,7 +363,7 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
 
 
 #ifdef NO_CPU_SHUTDOWN
-  while(!kthread_should_stop()){
+  while(!kthread_should_stop() && !vmeDone){
 #else
   while(!vmeDone){ 	// Run forever until user hits reset
 #endif
@@ -390,12 +401,14 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
       cycle_gps_time = timeSec;
     }
 #ifdef NO_CPU_SHUTDOWN
-    if((cycleNum % 2048) == 0) usleep_range(2,4);
+    if((cycleNum % 65536) == 0)  {
+        usleep_range(1,3);
+        printk("cycleNum = %d\n",cycleNum);
+    }
 #endif
 // Start of ADC Read **********************************************************************
     // Read ADC data
     status = iop_adc_read (padcinfo, cpuClock);
-
     // Try synching to 1PPS on ADC[0][31] if not using IRIG-B or TDS
     // Only try for 1 sec.
     if(!sync21pps)
@@ -423,13 +436,22 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
     }
 
 
-
+for(ploop=0;ploop<UNDERSAMPLE;ploop++)
+{
 
 // **************************************************************************************
 /// \> Call the front end specific application  ******************\n
 /// - -- This is where the user application produced by RCG gets called and executed. \n\n
+    // 
+    for(ii=0;ii<cdsPciModules.adcCount;ii++)
+    {
+        for(jj=0;jj<32;jj++)
+        {
+            adcval[ii][jj] = dWord[ii][jj][ploop];
+        }
+    }
     cpuClock[CPU_TIME_USR_START] = rdtsc_ordered();
-    iopDacEnable = feCode(cycleNum,dWord,dacOut,dspPtr[0],&dspCoeff[0],(struct CDS_EPICS *)pLocalEpics,0);
+    iopDacEnable = feCode(cycleNum,adcval,dacOut,dspPtr[0],&dspCoeff[0],(struct CDS_EPICS *)pLocalEpics,0);
     cpuClock[CPU_TIME_USR_END] = rdtsc_ordered();
 // **************************************************************************************
 //
@@ -437,8 +459,11 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
 // **************************************************************************************
     /// - ---- Reset ADC DMA Start Flag \n
     /// - --------- This allows ADC to dump next data set whenever it is ready
-    for(jj=0;jj<cdsPciModules.adcCount;jj++) gsc16ai64DmaEnable(jj);
+    // for(jj=0;jj<cdsPciModules.adcCount;jj++) gsc16ai64DmaEnable(jj);
+    // for(jj=0;jj<cdsPciModules.adcCount;jj++) gsc18ai32DmaEnable(jj);
     odcStateWord = 0;
+// for(ploop=0;ploop<UNDERSAMPLE;ploop++)
+// {
 //
 // ********************************************************************
 /// WRITE DAC OUTPUTS ***************************************** \n
@@ -449,8 +474,10 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
     // COMMENT OUT NEXT LINE FOR TEST STAND w/bad DAC cards. 
     if(dacTimingError) iopDacEnable = 0;
 #endif
+#if 0
     // Write out data to DAC modules
     dkiTrip = iop_dac_write();
+#endif
 
 
 // ***********************************************************************
@@ -500,11 +527,12 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
       }
     }
 
+#if 0
 /// \> Update duotone diag information
-    dt_diag.dac[(cycleNum + DT_SAMPLE_OFFSET) % CYCLE_PER_SECOND] = dWord[ADC_DUOTONE_BRD][DAC_DUOTONE_CHAN];
-    dt_diag.totalDac += dWord[ADC_DUOTONE_BRD][DAC_DUOTONE_CHAN];
-    dt_diag.adc[(cycleNum + DT_SAMPLE_OFFSET) % CYCLE_PER_SECOND] = dWord[ADC_DUOTONE_BRD][ADC_DUOTONE_CHAN];
-    dt_diag.totalAdc += dWord[ADC_DUOTONE_BRD][ADC_DUOTONE_CHAN];
+    dt_diag.dac[(cycleNum + DT_SAMPLE_OFFSET) % CYCLE_PER_SECOND] = dWord[ADC_DUOTONE_BRD][DAC_DUOTONE_CHAN][ploop];
+    dt_diag.totalDac += dWord[ADC_DUOTONE_BRD][DAC_DUOTONE_CHAN][ploop];
+    dt_diag.adc[(cycleNum + DT_SAMPLE_OFFSET) % CYCLE_PER_SECOND] = dWord[ADC_DUOTONE_BRD][ADC_DUOTONE_CHAN][ploop];
+    dt_diag.totalAdc += dWord[ADC_DUOTONE_BRD][ADC_DUOTONE_CHAN][ploop];
 
 // *****************************************************************
 /// \> Cycle 16, perform duotone diag calcs.
@@ -534,6 +562,7 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
         CDIO1616Input[0] = contec1616WriteOutputRegister(&cdsPciModules, tdsControl[0], CDIO1616Output[0]);
       }
     }
+#endif
 
 // *****************************************************************
 /// \> Cycle 18, Send timing info to EPICS at 1Hz
@@ -568,6 +597,7 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
       }
       pLocalEpics->epicsOutput.diagWord = diagWord;
       for(jj=0;jj<cdsPciModules.adcCount;jj++) {
+        pLocalEpics->epicsOutput.irigbTime = adcinfo.adcRdTimeErr[0];
         if(adcinfo.adcRdTimeErr[jj] > MAX_ADC_WAIT_ERR_SEC)
           pLocalEpics->epicsOutput.stateWord |= FE_ERROR_ADC;
           adcinfo.adcRdTimeErr[jj] = 0;
@@ -596,6 +626,8 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
     /// \> Check if code exit is requested
     if(cycleNum == MAX_MODULES) 
       vmeDone = stop_working_threads | checkEpicsReset(cycleNum, (struct CDS_EPICS *)pLocalEpics);
+
+#if 0
 // *****************************************************************
 	// If synced to 1PPS on startup, continue to check that code
 	// is still in sync with 1PPS.
@@ -615,6 +647,7 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
       // If not, set sync error flag
       if(onePpsTime > 1) pLocalEpics->epicsOutput.timeErr |= TIME_ERR_1PPS;
     }
+#endif
 
 // Following is only used on automated test system
 #ifdef DIAG_TEST
@@ -641,6 +674,7 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
 // *****************************************************************
 #ifndef NO_DAQ
 		
+  if(ploop == 0) {
     // Call daqLib
     pLocalEpics->epicsOutput.daqByteCnt = 
     daqWrite(1,dcuId,daq,DAQ_RATE,testpoint,dspPtr[0],0,(int *)(pLocalEpics->epicsOutput.gdsMon),xExc,pEpicsDaq);
@@ -652,6 +686,7 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
     else odcStateWord &= ~(ODC_EXC_SET);
     if(pLocalEpics->epicsOutput.daqByteCnt > DAQ_DCU_RATE_WARNING) 
       feStatus |= FE_ERROR_DAQ;
+    }
 #endif
 
 // *****************************************************************
@@ -724,10 +759,14 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
       // from the RT code ie loops would be working with wrong input data.
       if (adcinfo.chanHop) {
         pLocalEpics->epicsOutput.stateWord = FE_ERROR_ADC;
+        pLocalEpics->epicsOutput.fe_status = CHAN_HOP_ERROR;
+#if 0
         stop_working_threads = 1;
         vmeDone = 1;
-        pLocalEpics->epicsOutput.fe_status = CHAN_HOP_ERROR;
         continue;    
+#endif
+      } else {
+        pLocalEpics->epicsOutput.fe_status = NORMAL_RUN;
       }
     }
 
@@ -830,6 +869,8 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
 // *****************************************************************
 // Update end of cycle information
 // *****************************************************************
+if(ploop == 0)
+{
     // Capture end of cycle time.
     cpuClock[CPU_TIME_CYCLE_END] = rdtsc_ordered();
 
@@ -842,6 +883,7 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
     // For IOP, more interested in time to get thru ADC read code and send to slave apps
     timeinfo.usrTime = (cpuClock[CPU_TIME_USR_START] - cpuClock[CPU_TIME_CYCLE_START])/CPURATE;
     if(timeinfo.usrTime > timeinfo.usrHoldTime) timeinfo.usrHoldTime = timeinfo.usrTime;
+}
 
     /// \> Update internal cycle counters
     cycleNum += 1;
@@ -867,6 +909,7 @@ adcInfo_t *padcinfo = (adcInfo_t *)&adcinfo;
       /* Increment the internal cycle counter */
       subcycle ++;                                                
     }
+  }
 
 /// \> If not exit request, then continue INFINITE LOOP  *******
   }
diff --git a/src/fe/map.c b/src/fe/map.c
index 1a23446bdab8daea4a29b2554ab5f6bed7312afd..a0e64cc5da77d421d6ab506a2cf6e23091e0ff8f 100644
--- a/src/fe/map.c
+++ b/src/fe/map.c
@@ -27,7 +27,7 @@
 #include <drv/vmic5565.c>
 #include <drv/symmetricomGps.c>
 #include <drv/spectracomGPS.c>
-#include <drv/gsc18ai6.c>
+#include <drv/gsc18ai32.c>
 
 
 
@@ -66,8 +66,8 @@ int mapPciModules(CDS_HARDWARE *pCds)
   int status;
   int i;
   int modCount = 0;
-//  int fast_adc_cnt = 0;
 #ifndef ADC_SLAVE
+  int fast_adc_cnt = 0;
   int adc_cnt = 0;
 #endif
   int dac_cnt = 0;
@@ -190,19 +190,17 @@ int mapPciModules(CDS_HARDWARE *pCds)
 		}
 		adc_cnt++;
 	}
-#endif
         // if found, check if it is a Fast ADC module
     	// TODO: for the time of testing of the 18-bit board, it returned same PCI device number as the 16-bit fast GS board
 	// This number will most likely change in the future.
-	#if 0
-        if((dacdev->subsystem_device == FADC_SS_ID) && (dacdev->subsystem_vendor == PLX_VID))
+        if((dacdev->subsystem_device == ADC_18AI32_SS_ID) && (dacdev->subsystem_vendor == PLX_VID))
         {
 		use_it = 0;
 		if (pCds->cards) {
 			use_it = 0;
 			/* See if ought to use this one or not */
 			for (i = 0; i < pCds->cards; i++) {
-				if (pCds->cards_used[i].type == GSC_18AISS6C
+				if (pCds->cards_used[i].type == GSC_18AI32SSC1M
 				    && pCds->cards_used[i].instance == fast_adc_cnt) {
 					use_it = 1;
 					break;
@@ -213,13 +211,13 @@ int mapPciModules(CDS_HARDWARE *pCds)
                    printk("fast adc card on bus %x; device %x\n",
                         dacdev->bus->number,
 			PCI_SLOT(dacdev->devfn));
-                   status = mapFadc(pCds, dacdev);
+                   status = gsc18ai32Init(pCds, dacdev);
                    modCount ++;
 		}
 		fast_adc_cnt++;
         }
-	#endif
   }
+#endif
 
   dacdev = NULL;
   status = 0;
diff --git a/src/fe/timing.c b/src/fe/timing.c
index d1f16d21e8d9dc6e78a226456b6d526cbef112b3..b71e0c1dbd3561742e95e02badc884950f04af3a 100644
--- a/src/fe/timing.c
+++ b/src/fe/timing.c
@@ -128,7 +128,7 @@ inline void sendTimingDiags2Epics(CDS_EPICS *pLocalEpics,
     timeinfo->timeHoldWhenHold = timeinfo->timeHoldWhen;
     timeinfo->usrHoldTime = 0;
 
-    pLocalEpics->epicsOutput.adcWaitTime = adcinfo->adcHoldTimeAvg/CYCLE_PER_SECOND;
+    pLocalEpics->epicsOutput.adcWaitTime = adcinfo->adcHoldTimeAvg/(CYCLE_PER_SECOND / UNDERSAMPLE);
     pLocalEpics->epicsOutput.adcWaitMin = adcinfo->adcHoldTimeMin;
     pLocalEpics->epicsOutput.adcWaitMax = adcinfo->adcHoldTimeMax;
 
diff --git a/src/include/controller.h b/src/include/controller.h
index 5092c7a568d155e97982e91b121d6ebc3e93bb22..56cfe1548657a11462a8bdbd7e390a7f16074c7a 100644
--- a/src/include/controller.h
+++ b/src/include/controller.h
@@ -94,6 +94,32 @@ char fp [64*1024];
 #define NORMAL_RUN			7
 
 // Define standard values based on code rep rate **************************************
+#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 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 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)
@@ -126,6 +152,7 @@ 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
@@ -296,7 +323,7 @@ VME_COEF *pCoeff[NUM_SYSTEMS];                                  // Ptr to SFM co
 
 // ADC Variables
 /// Array of ADC values
-double dWord[MAX_ADC_MODULES][MAX_ADC_CHN_PER_MOD];             // ADC read values
+double dWord[MAX_ADC_MODULES][MAX_ADC_CHN_PER_MOD][16];             // ADC read values
 /// List of ADC channels used by this app. Used to determine if downsampling required.
 unsigned int dWordUsed[MAX_ADC_MODULES][MAX_ADC_CHN_PER_MOD];   // ADC chans used by app code
 
diff --git a/src/include/drv/cdsHardware.h b/src/include/drv/cdsHardware.h
index 2765550a635996d29c43fd2dc8983432d15f662d..e42813a1e1e83572cea8860647ab0029900adc7d 100644
--- a/src/include/drv/cdsHardware.h
+++ b/src/include/drv/cdsHardware.h
@@ -80,7 +80,8 @@ typedef struct CDS_REMOTE_NODES {
 #define MAX_ADC_WAIT_CYCLE	17
 #define DUMMY_ADC_VAL		0xf000000	// Dummy value for test last ADC channel has arrived
 #define ADC_1ST_CHAN_MARKER	0xf0000		// Only first ADC channel should have upper bits set as first chan marker.
-#define IOP_IO_RATE		65536
+// #define IOP_IO_RATE		65536
+#define IOP_IO_RATE		524288
 #define ADC_DUOTONE_BRD		0
 #define ADC_DUOTONE_CHAN	31
 #define DAC_DUOTONE_CHAN	30
diff --git a/src/include/drv/fm10Gen.c b/src/include/drv/fm10Gen.c
index 278417882f3cdaa2098d843bf8b97470821f6a04..96fbac7bcd1c376905a0b4d201189abfd97d34f3 100644
--- a/src/include/drv/fm10Gen.c
+++ b/src/include/drv/fm10Gen.c
@@ -55,7 +55,7 @@ const UINT32 fltrConst[17] = {16, 64, 256, 1024, 4096, 16384,
 				     0x2000000,0x8000000
 				     };
 
-#if defined(SERVO16K) || defined(SERVO32K) || defined(SERVO64K) || defined(SERVO128K) || defined(SERVO256K)
+#if defined(SERVO16K) || defined(SERVO512K) || defined(SERVO32K) || defined(SERVO64K) || defined(SERVO128K) || defined(SERVO256K) || defined(SERVO1024K)
 double sixteenKAvgCoeff[9] = {1.9084759e-12,
 				     -1.99708675982420, 0.99709029700517, 2.00000005830747, 1.00000000739582,
 				     -1.99878510620232, 0.99879373895648, 1.99999994169253, 0.99999999260419};
@@ -69,7 +69,11 @@ double twoKAvgCoeff[9] = {7.705446e-9,
 
 #ifdef SERVO16K
 #define avgCoeff sixteenKAvgCoeff
-#elif defined(SERVO32K) || defined(SERVO64K) || defined(SERVO128K) || defined(SERVO256K)
+#elif defined(SERVO32K) || defined(SERVO64K) || defined(SERVO128K) || defined(SERVO256K) 
+#define avgCoeff sixteenKAvgCoeff
+#elif defined(SERVO1024K)
+#define avgCoeff sixteenKAvgCoeff
+#elif defined(SERVO512K)
 #define avgCoeff sixteenKAvgCoeff
 #elif defined(SERVO2K)
 #define avgCoeff twoKAvgCoeff
@@ -80,6 +84,12 @@ double twoKAvgCoeff[9] = {7.705446e-9,
 #error need to define 2k or 16k or mixed
 #endif
 
+#ifdef SERVO1024K
+  #define FE_RATE	1048576
+#endif
+#ifdef SERVO512K
+  #define FE_RATE	524288
+#endif
 #ifdef SERVO256K
   #define FE_RATE	262144
 #endif
@@ -245,6 +255,10 @@ const int rate = (2*32768);
 const int rate = (4*32768);
 #elif defined(SERVO256K)
 const int rate = (8*32768);
+#elif defined(SERVO512K)
+const int rate = (16*32768);
+#elif defined(SERVO1024K)
+const int rate = (32*32768);
 #endif
 
 /* Convert opSwitchE bits into the 16-bit FiltCtrl2 Ctrl output format */
@@ -289,7 +303,7 @@ inline int readCoefVme(COEF *filtC,FILT_MOD *fmt, int bF, int sF, volatile VME_C
 #ifdef FIR_FILTERS
 	if (filtC->coeffs[ii].filterType[jj] < 0 || filtC->coeffs[ii].filterType[jj] > MAX_FIR_MODULES) {
 		filtC->coeffs[ii].filterType[jj] = 0;
-		printf("Corrupted data coming from Epics: module=%d filter=%d filterType=%d\n", 
+		// printk("Corrupted data coming from Epics: module=%d filter=%d filterType=%d\n", 
 			ii, jj, pRfmCoeff->vmeCoeffs[ii].filterType[jj]);
 		return 1;
 	}
@@ -301,9 +315,9 @@ inline int readCoefVme(COEF *filtC,FILT_MOD *fmt, int bF, int sF, volatile VME_C
 
 	if (filtC->coeffs[ii].filterType[jj] == 0) {
 	  if (filtC->coeffs[ii].filtSections[jj] > 10) {
-		printf("Corrupted Epics data:  module=%d filter=%d filterType=%d filtSections=%d\n",
-			ii, jj, pRfmCoeff->vmeCoeffs[ii].filterType[jj],
-			filtC->coeffs[ii].filtSections[jj]);
+		// printk("Corrupted Epics data:  module=%d filter=%d filterType=%d filtSections=%d\n",
+			// ii, jj, pRfmCoeff->vmeCoeffs[ii].filterType[jj],
+			// filtC->coeffs[ii].filtSections[jj]);
 		return 1;
 	  }
           for(kk=0;kk<filtC->coeffs[ii].filtSections[jj]*4+1;kk++) {
@@ -351,7 +365,7 @@ int readCoefVme2(COEF *filtC,FILT_MOD *fmt, int modNum1, int filtNum, int cycle,
 
 #ifdef FIR_FILTERS
   if (type < 0 || type > MAX_FIR_MODULES) {
-	printf("Vme2 bad Epics filter type: module=%d filter=%d filterType=%d\n", 
+	// printk("Vme2 bad Epics filter type: module=%d filter=%d filterType=%d\n", 
 	modNum1, filtNum, type);
   }
 #endif
@@ -438,7 +452,7 @@ int readCoefVme2(COEF *filtC,FILT_MOD *fmt, int modNum1, int filtNum, int cycle,
 	if (filtNum == 9) { /* Last filter loaded in this filter bank */
 	    unsigned int vme_crc =  pRfmCoeff->vmeCoeffs[modNum1].crc;
 	    if (localCoeff.crc != vme_crc) {
-	      printf("vme_crc = 0x%x; local crc = 0x%x\n", vme_crc, localCoeff.crc);
+	      // printk("vme_crc = 0x%x; local crc = 0x%x\n", vme_crc, localCoeff.crc);
 	      // return -1;
 	    }
 	}
@@ -727,6 +741,7 @@ filterModuleD2(FILT_MOD *pFilt,     /* Filter module data  */
   double output;
   double fmInput;
   int id = 0;                  /* System number (HEPI) */
+      extern int cycleNum;
 
   /* Do the shift to match the bits in the the opSwitchE variable so I can do "==" comparisons */
   UINT32 opSwitchP = pFilt->inputs[modNum].opSwitchP >> 1;
@@ -848,7 +863,7 @@ filterModuleD2(FILT_MOD *pFilt,     /* Filter module data  */
 	  pC->prevFirOutput[filterType] = filtData;
 	} else {
 	  filtData = filterType;
-	  printf("module %d; filter %d; filterType = %d\n", modNum, ii, filterType);
+	  // printk("module %d; filter %d; filterType = %d\n", modNum, ii, filterType);
 	}
       }
     } else
diff --git a/src/include/drv/gsc16ai64.c b/src/include/drv/gsc16ai64.c
index 7a98a34c0fb66afba81a20180ca11bfed94e1701..92d678a337a984225a5ca43061fbe68966b9ba3a 100644
--- a/src/include/drv/gsc16ai64.c
+++ b/src/include/drv/gsc16ai64.c
@@ -131,11 +131,13 @@ int gsc16ai64WaitDmaDone(int module, int *data)
 ///< the timing slave are turned OFF ie during initialization process.
 ///	@param[in] adcCount Total number of ADC modules to start DMA.
 // *****************************************************************************
-int gsc16ai64Enable(int adcCount)
+int gsc16ai64Enable(CDS_HARDWARE *pHardware)
 {
   int ii;
-  for(ii=0;ii<adcCount;ii++)
+  for(ii=0;ii<pHardware->adcCount;ii++)
   {
+    if(pHardware->adcType[ii] == GSC_16AI64SSA)
+    {
 	  /// Enable demand DMA mode ie auto DMA data to computer memory when 
 	  ///< GSAI_THRESHOLD data points in ADC FIFO.
           adcPtr[ii]->BCR &= ~(GSAI_DMA_DEMAND_MODE);
@@ -147,6 +149,7 @@ int gsc16ai64Enable(int adcCount)
           adcPtr[ii]->IDBC = (GSAI_CLEAR_BUFFER | GSAI_THRESHOLD);
 	  /// Enable sync via external clock input.
           adcPtr[ii]->BCR |= GSAI_ENABLE_X_SYNC;
+    }
   }
   return(0);
 }
diff --git a/src/include/drv/iop_adc_functions.c b/src/include/drv/iop_adc_functions.c
index fabeaca9edaaabf44d1cb35fa4f16aa7a774b183..1dd015a33d9e89e0d6fdfbd6c469bec7ebd6a98b 100644
--- a/src/include/drv/iop_adc_functions.c
+++ b/src/include/drv/iop_adc_functions.c
@@ -12,14 +12,20 @@ inline int iop_adc_init(adcInfo_t *adcinfo)
   for(jj=0;jj<cdsPciModules.adcCount;jj++)
   {
 	  // Setup the DMA registers
+      if (cdsPciModules.adcType[jj] == GSC_18AI32SSC1M)  
+      {
+	    status = gsc18ai32DmaSetup(jj);
+      } else {
 	  status = gsc16ai64DmaSetup(jj);
+      }
 	  // Preload input memory with dummy variables to test that new ADC data has arrived.
 	  adcDummyData = (int *)cdsPciModules.pci_adc[jj];
 	  // Write a dummy 0 to first ADC channel location
 	  // This location should never be zero when the ADC writes data as it should always
 	  // have an upper bit set indicating channel 0.
           *adcDummyData = 0x0;
-          if (cdsPciModules.adcType[jj] == GSC_18AISS6C)  adcDummyData += 5;
+          // if (cdsPciModules.adcType[jj] == GSC_18AI32SSC1M)  adcDummyData += 63;
+          if (cdsPciModules.adcType[jj] == GSC_18AI32SSC1M)  adcDummyData += GSAF_8_OFFSET;
           else adcDummyData += 31;
 	  // Write a number into the last channel which the ADC should never write ie no
 	  // upper bits should be set in channel 31.
@@ -125,7 +131,7 @@ inline int sync_adc_2_1pps() {
 // ADC Read *****************************************************************
 inline int iop_adc_read (adcInfo_t *adcinfo,int cpuClk[])
 {
-    int ii,jj;
+    int kk;
     volatile int *packedData;
     int limit;
     int mask;
@@ -133,14 +139,17 @@ inline int iop_adc_read (adcInfo_t *adcinfo,int cpuClk[])
     int num_outs;
     int ioMemCntr = 0;
     int adcStat = 0;
+    int card;
+    int chan;
 
     // Read ADC data
-    for(jj=0;jj<cdsPciModules.adcCount;jj++)
+    for(card=0;card<cdsPciModules.adcCount;card++)
     {
     /// - ---- ADC DATA RDY is detected when last channel in memory no longer contains the
     /// dummy variable written during initialization and reset after the read.
-        packedData = (int *)cdsPciModules.pci_adc[jj];
-        packedData += 31;
+        packedData = (int *)cdsPciModules.pci_adc[card];
+        if (cdsPciModules.adcType[card] == GSC_18AI32SSC1M)  packedData += GSAF_8_OFFSET;
+        else packedData += 31;
 		
 	cpuClk[CPU_TIME_RDY_ADC] = rdtsc_ordered();
         do {
@@ -153,42 +162,44 @@ inline int iop_adc_read (adcInfo_t *adcinfo,int cpuClk[])
 
 
         /// - ---- Added ADC timing diagnostics to verify timing consistent and all rdy together.
-        if(jj==0) {
-            adcinfo->adcRdTime[jj] = (cpuClk[CPU_TIME_ADC_WAIT] - cpuClk[CPU_TIME_CYCLE_START]) / CPURATE;
-	    if(adcinfo->adcRdTime[jj] > 1000) adcStat = ADC_BUS_DELAY;
-	    if(adcinfo->adcRdTime[jj] < 13) adcStat = ADC_SHORT_CYCLE;
+        if(card==0) {
+            adcinfo->adcRdTime[card] = (cpuClk[CPU_TIME_ADC_WAIT] - cpuClk[CPU_TIME_CYCLE_START]) / CPURATE;
+	    if(adcinfo->adcRdTime[card] > 1000) adcStat = ADC_BUS_DELAY;
+	    if(adcinfo->adcRdTime[card] < 13) adcStat = ADC_SHORT_CYCLE;
 #ifdef TIME_MASTER
             pcieTimer->gps_time = timeSec;
             pcieTimer->cycle = cycleNum;
             clflush_cache_range(&pcieTimer->gps_time,16);
 #endif
         } else {
-            adcinfo->adcRdTime[jj] = adcinfo->adcWait;
+            adcinfo->adcRdTime[card] = adcinfo->adcWait;
         }
 
-        if(adcinfo->adcRdTime[jj] > adcinfo->adcRdTimeMax[jj]) adcinfo->adcRdTimeMax[jj] = 
-            adcinfo->adcRdTime[jj];
+        if(adcinfo->adcRdTime[card] > adcinfo->adcRdTimeMax[card]) adcinfo->adcRdTimeMax[card] = 
+            adcinfo->adcRdTime[card];
 
-        if((jj==0) && (adcinfo->adcRdTimeMax[jj] > MAX_ADC_WAIT_CARD_0)) 
-            adcinfo->adcRdTimeErr[jj] ++;
+        // if((card==0) && (adcinfo->adcRdTimeMax[card] > MAX_ADC_WAIT_CARD_0)) 
+        if((card==0) && (adcinfo->adcRdTime[card] > 20)) 
+            adcinfo->adcRdTimeErr[card] ++;
 
-        if((jj!=0) && (adcinfo->adcRdTimeMax[jj] > MAX_ADC_WAIT_CARD_S)) 
-            adcinfo->adcRdTimeErr[jj] ++;
+        if((card!=0) && (adcinfo->adcRdTimeMax[card] > MAX_ADC_WAIT_CARD_S)) 
+            adcinfo->adcRdTimeErr[card] ++;
 
         /// - --------- If data not ready in time, abort.
         /// Either the clock is missing or code is running too slow and ADC FIFO
         /// is overflowing.
         if (adcinfo->adcWait >= MAX_ADC_WAIT) {
+            // printk("timeout %d %d \n",jj,adcinfo->adcWait);
             pLocalEpics->epicsOutput.stateWord = FE_ERROR_ADC;
             pLocalEpics->epicsOutput.diagWord |= ADC_TIMEOUT_ERR;
             pLocalEpics->epicsOutput.fe_status = ADC_TO_ERROR;
             stop_working_threads = 1;
             vmeDone = 1;
-            // printf("timeout %d %d \n",jj,adcinfo->adcWait);
             continue;
+            // return 0;
         }
 
-        if(jj == 0) 
+        if(card == 0) 
         {
         // Capture cpu clock for cpu meter diagnostics
 	    cpuClk[CPU_TIME_CYCLE_START] = rdtsc_ordered();
@@ -210,14 +221,17 @@ inline int iop_adc_read (adcInfo_t *adcinfo,int cpuClk[])
         }
 
         /// \> Read adc data
-        packedData = (int *)cdsPciModules.pci_adc[jj];
+        packedData = (int *)cdsPciModules.pci_adc[card];
         /// - ---- First, and only first, channel should have upper bit marker set.
         /// If not, have a channel hopping error.
-        if(!(*packedData & ADC_1ST_CHAN_MARKER)) 
+        if((unsigned int)*packedData  > 65535) 
+        // if(!((unsigned int)*packedData & ADC_1ST_CHAN_MARKER)) 
         {
-            adcinfo->adcChanErr[jj] = 1;
+            // adcinfo->adcChanErr[jj] = 1;
+            adcinfo->chanHop = 0;
+            // pLocalEpics->epicsOutput.stateWord |= FE_ERROR_ADC;
+        } else {
             adcinfo->chanHop = 1;
-            pLocalEpics->epicsOutput.stateWord |= FE_ERROR_ADC;
         }	
 
         limit = OVERFLOW_LIMIT_16BIT;
@@ -225,55 +239,75 @@ inline int iop_adc_read (adcInfo_t *adcinfo,int cpuClk[])
        	offset = GSAI_DATA_CODE_OFFSET;
         mask = GSAI_DATA_MASK;
         num_outs = GSAI_CHAN_COUNT;
+        if (cdsPciModules.adcType[card] == GSC_18AI32SSC1M) 
+        {
+            num_outs = 8;
+        }
         /// - ---- Determine next ipc memory location to load ADC data
         ioMemCntr = (cycleNum % IO_MEMORY_SLOTS);
 
         /// - ----  Read adc data from PCI mapped memory into local variables
-        for(ii=0;ii<num_outs;ii++)
+        for(kk=0;kk<UNDERSAMPLE;kk++)
+        {
+        for(chan=0;chan<num_outs;chan++)
         {
         // adcData is the integer representation of the ADC data
-            adcinfo->adcData[jj][ii] = (*packedData & mask);
-            adcinfo->adcData[jj][ii]  -= offset;
+            adcinfo->adcData[card][chan] = (*packedData & mask);
+            adcinfo->adcData[card][chan]  -= offset;
 #ifdef DEC_TEST
-            if(ii==0)
+            if(chan==0)
             {
-                adcinfo->adcData[jj][ii] = dspPtr[0]->data[0].exciteInput;
+                adcinfo->adcData[card][chan] = dspPtr[0]->data[0].exciteInput;
             }
 #endif
             // dWord is the double representation of the ADC data
             // This is the value used by the rest of the code calculations.
-            dWord[jj][ii] = adcinfo->adcData[jj][ii];
+            dWord[card][chan][kk] = adcinfo->adcData[card][chan];
             /// - ----  Load ADC value into ipc memory buffer
-            ioMemData->iodata[jj][ioMemCntr].data[ii] = adcinfo->adcData[jj][ii];
+            ioMemData->iodata[card][ioMemCntr].data[chan] = adcinfo->adcData[card][chan];
+        /// - ---- Check for ADC overflows
+            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;
+            }
             packedData ++;
         }
 
         /// - ---- Write GPS time and cycle count as indicator to slave that adc data is ready
-        ioMemData->gpsSecond = timeSec;;
-        ioMemData->iodata[jj][ioMemCntr].timeSec = timeSec;;
-        ioMemData->iodata[jj][ioMemCntr].cycle = cycleNum;
+        ioMemData->gpsSecond = timeSec;
+        ioMemData->iodata[card][ioMemCntr].timeSec = timeSec;
+        ioMemData->iodata[card][ioMemCntr].cycle = cycleNum + kk;
+        ioMemCntr ++;
 
+#if 0
         /// - ---- Check for ADC overflows
-        for(ii=0;ii<num_outs;ii++)
+        for(chan=0;chan<num_outs;chan++)
         {
-            if((adcinfo->adcData[jj][ii] > limit) || (adcinfo->adcData[jj][ii] < -limit))
+            if((adcinfo->adcData[card][chan] > limit) || (adcinfo->adcData[card][chan] < -limit))
             {
-                adcinfo->overflowAdc[jj][ii] ++;
-                pLocalEpics->epicsOutput.overflowAdcAcc[jj][ii] ++;
+                adcinfo->overflowAdc[card][chan] ++;
+                pLocalEpics->epicsOutput.overflowAdcAcc[card][chan] ++;
                 overflowAcc ++;
-                adcinfo->adcOF[jj] = 1;
+                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[jj];
+        packedData = (int *)cdsPciModules.pci_adc[card];
         *packedData = 0x0;
 
-        if (cdsPciModules.adcType[jj] == GSC_18AISS6C) packedData += GSAF_CHAN_COUNT_M1;
+        if (cdsPciModules.adcType[card] == GSC_18AI32SSC1M) packedData += GSAF_8_OFFSET;
         else packedData += GSAI_CHAN_COUNT_M1;
 
         *packedData = DUMMY_ADC_VAL;
+         gsc18ai32DmaEnable(card);
 
 #ifdef DIAG_TEST
 // For DIAGS ONLY !!!!!!!!
@@ -282,7 +316,7 @@ inline int iop_adc_read (adcInfo_t *adcinfo,int cpuClk[])
 // -- Less than normal will result in ADC timeout.
 // In both cases, real-time kernel code should exit with errors to dmesg
         if(pLocalEpics->epicsInput.bumpAdcRd != 0) {
-            gsc16ai64DmaBump(jj,pLocalEpics->epicsInput.bumpAdcRd);
+            gsc16ai64DmaBump(card,pLocalEpics->epicsInput.bumpAdcRd);
             pLocalEpics->epicsInput.bumpAdcRd = 0;
         }
 #endif
@@ -415,7 +449,7 @@ inline int iop_adc_read_32 (adcInfo_t *adcinfo,int cpuClk[])
             adcinfo->adcData[jj][ii]  -= offset;
             // dWord is the double representation of the ADC data
             // This is the value used by the rest of the code calculations.
-            dWord[jj][ii] = adcinfo->adcData[jj][ii];
+            dWord[jj][ii][nn] = adcinfo->adcData[jj][ii];
             /// - ----  Load ADC value into ipc memory buffer
             ioMemData->iodata[jj][ioMemCntr].data[ii] = adcinfo->adcData[jj][ii];
             packedData ++;
diff --git a/src/include/fe.h b/src/include/fe.h
index 178b776991ef28e68a7c74ce340f0639aed83fa2..86f24ec892273ee70a5ae1f1be49737326b4c9c6 100644
--- a/src/include/fe.h
+++ b/src/include/fe.h
@@ -37,7 +37,11 @@ int rioInputInput[MAX_DIO_MODULES];
 int gainRamp(float gainReq, int rampTime, int id, float *gain, int gainRate);
 unsigned int CDO32Output[MAX_DIO_MODULES];
 
-#if defined(SERVO256K)
+#if defined(SERVO1024K)
+#define CYCLE_PER_SECOND (1024*1024)
+#elif defined(SERVO512K)
+#define CYCLE_PER_SECOND (512*1024)
+#elif defined(SERVO256K)
 #define CYCLE_PER_SECOND (256*1024)
 #elif defined(SERVO128K)
 #define CYCLE_PER_SECOND (128*1024)