diff --git a/src/epics/util/feCodeGen.pl b/src/epics/util/feCodeGen.pl index 4c1eb2218bc02ef7e7ee2c3a5f1ff7d0c713c6ee..8289b8b7b9a317d12b08c22ca23f74fb9b8d6830 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 8441334378ae427bc120bb9a4096f17a8ce58344..77be6eb2b398ec6eab1745ce3fa4410a8617973d 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 42967890e419c408c3024465a5d854edc090a8b8..7d2612636060666effd5281ee1c39bef0042f067 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 de0a3fc8c9add7bc732b827e798d160ede9436bf..dba328a875ee317dce623602ecfd1d5d2a5bf3d3 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 56cfe1548657a11462a8bdbd7e390a7f16074c7a..fd1c9780733956488977cd72c162b8f7c952bf7f 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 1dd015a33d9e89e0d6fdfbd6c469bec7ebd6a98b..79201ee0330c5e7d86726a408d231e8d2b40d686 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 !!!!!!!!