diff --git a/src/epics/util/feCodeGen.pl b/src/epics/util/feCodeGen.pl index f22d61d47df10357942a7d58efd5b37753a7fdef..87c6e912494f7828e3ef66ec69a5ad7f45fd5cfa 100755 --- a/src/epics/util/feCodeGen.pl +++ b/src/epics/util/feCodeGen.pl @@ -758,16 +758,50 @@ for($ii=0;$ii<$nonSubCnt;$ii++) } } -#// - Remove all parts which will not require further processing in the code for the part -#// total. \n +#// - Remove all parts which will not require further processing in the code for the part +#// total, also do a part check for blocks with different capitalization that are going to +#// emit c code that will be lowercased (causing collisions) $ftotal = $partCnt; - for($kk=0;$kk<$partCnt;$kk++) - { - if(($partType[$kk] eq "INPUT") || ($partType[$kk] eq "OUTPUT") || ($partType[$kk] eq "BUSC") || ($partType[$kk] eq "BUSS") || ($partType[$kk] eq "EpicsIn") || ($partType[$kk] eq "TERM") || ($partType[$kk] eq "FROM") || ($partType[$kk] eq "GOTO") || ($partType[$kk] eq "GROUND") || ($partType[$kk] eq "CONSTANT") || ($partType[$kk] eq "Adc") || ($partType[$kk] eq "Gps") || ($partType[$kk] eq "StateWord") || ($partType[$kk] eq "ModelRate") || ($partType[$kk] eq "EXC")) - { - $ftotal --; - } - } + +my %seen; #Hash that keeps track of the names we have seen before +my %noCode = map {$_ => 1} qw(INPUT OUTPUT BUSC BUSS FROM GOTO); #Hash of non-generating parts +my @duplicates = (); + +for($kk=0;$kk<$partCnt;$kk++) +{ + if(($partType[$kk] eq "INPUT") || ($partType[$kk] eq "OUTPUT") || ($partType[$kk] eq "BUSC") + || ($partType[$kk] eq "BUSS") || ($partType[$kk] eq "EpicsIn") || ($partType[$kk] eq "TERM") + || ($partType[$kk] eq "FROM") || ($partType[$kk] eq "GOTO") || ($partType[$kk] eq "GROUND") + || ($partType[$kk] eq "CONSTANT") || ($partType[$kk] eq "Adc") || ($partType[$kk] eq "Gps") + || ($partType[$kk] eq "StateWord") || ($partType[$kk] eq "ModelRate") || ($partType[$kk] eq "EXC")) + { + $ftotal --; + } + + # Check to see if we have a part with the same lower case name, + # and neither parts are of a no code generating type + if ( exists $seen{ lc $xpartName[$kk] } + and not exists $noCode{$partType[$kk]} + and not exists $noCode{ $seen{ lc $xpartName[$kk] }[1] } ) + { + push(@duplicates, "\tFirst (part, type) is: ($xpartName[$kk], $partType[$kk]),". + " other part is ($seen{ lc $xpartName[$kk]}[0], $seen{ lc $xpartName[$kk]}[1])\n"); + } + else + { + my @val = ($xpartName[$kk], $partType[$kk]); + $seen{ lc $xpartName[$kk] } = \@val; + } +} + +if ( scalar(@duplicates) > 0) #If we found 1 or more issues +{ + my $whole_error = "ERROR - Some part(s) failed the duplicate name check. " . + "Two parts, that generate code, with the same name (but different capitalization) were found.\n" . + "This can cause an issue with code generation, please rename one of the parts, from each pair.\n"; + $whole_error = $whole_error . join('', @duplicates); + die $whole_error . "\n"; +} print "Total parts to process $ftotal\n"; diff --git a/src/epics/util/lib/Filt.pm b/src/epics/util/lib/Filt.pm index 815fefa0dde7301836ddbeea32d35a47acdf8fb2..52dcb44f2746ab88149bdc079b8933f6cefbf7fa 100644 --- a/src/epics/util/lib/Filt.pm +++ b/src/epics/util/lib/Filt.pm @@ -80,6 +80,13 @@ sub frontEndCode { my ($i) = @_; my $calcExp = "// FILTER MODULE"; if ($::ppFIR[$i] == 1) { + + if ( $::modelrate ne 2 and $::modelrate ne 4 ) + { + die ("Error - The model has a FIR filter in it but has a rate of " . $::modelrate . + "K, only 2K and 4K models support FIR filters."); + } + $calcExp .= " (PolyPhase FIR)"; } $calcExp .= ": $::xpartName[$i]\n"; diff --git a/src/epics/util/lib/IPCx.pm b/src/epics/util/lib/IPCx.pm index 7f4d9e16a0e1bcb6b3351756e331dacf854a007d..bc283610eb945dcb8aef8abcf7b6447dad74efac 100644 --- a/src/epics/util/lib/IPCx.pm +++ b/src/epics/util/lib/IPCx.pm @@ -673,6 +673,7 @@ $ipcxRcvrCnt = 0; $::ipcxParts[$ipcxAdd[$jj][0]][3] = $::targetHost; $::ipcxParts[$ipcxAdd[$jj][0]][4] = $ipcxMaxNum[$ipcxTypeIndex]; $::ipcxParts[$ipcxAdd[$jj][0]][5] = $::skeleton; + $::ipcxParts[$ipcxAdd[$jj][0]][9] = 1; #Because we are adding this, it must be a sender IPC $ipcxNew++; } diff --git a/src/fe/map.c b/src/fe/map.c index 2684bab494da0f1fbf69693746dc9dab01019843..48af4f83c8be07eb4a3e78a027fb00d3fa3b9a05 100644 --- a/src/fe/map.c +++ b/src/fe/map.c @@ -260,6 +260,11 @@ mapPciModulesRealCards( CDS_HARDWARE* pCds ) dacdev = NULL; status = 0; + // initialize dac duotone multipliers/divisors in case + // we don't have one or the other of DAC or ADC cards + pCds->adcDuoToneDivisor[ 0 ] = 1; + pCds->dacDuoToneMultiplier[ 0 ] = 1; + modCount = map_cards_2_slots ( &cdsPciModules ) ; // Map and Initialize ADC and DAC modules diff --git a/src/include/drv/cdsHardware.h b/src/include/drv/cdsHardware.h index 4ff90069dcae843b7a221a7f4836edbf56925aa6..c3bf3bf531a63a2d4d4b9a5a161ccd1f94e36b97 100644 --- a/src/include/drv/cdsHardware.h +++ b/src/include/drv/cdsHardware.h @@ -209,6 +209,7 @@ typedef struct CDS_HARDWARE{ int dacCount; /* Number of DAC modules found */ volatile int * pci_dac[MAX_DAC_MODULES]; /* Remapped addresses of DAC modules */ int dacType[MAX_DAC_MODULES]; + int dacDuoToneMultiplier[MAX_DAC_MODULES]; /* scale amplitude of duotone up for higher bit DACs */ int dacInstance[MAX_DAC_MODULES]; int dacSlot[MAX_DAC_MODULES]; int dacConfig[MAX_DAC_MODULES]; @@ -217,6 +218,7 @@ typedef struct CDS_HARDWARE{ int adcCount; /* Number of ADC modules found */ volatile int *pci_adc[MAX_ADC_MODULES]; /* Remapped addresses of ADC modules */ int adcType[MAX_ADC_MODULES]; + int adcDuoToneDivisor[MAX_ADC_MODULES]; /* scale amplitude of duotone down for higher bit ADCs */ int adcInstance[MAX_ADC_MODULES]; int adcSlot[MAX_ADC_MODULES]; int adcChannels[MAX_ADC_MODULES]; diff --git a/src/include/drv/gsc16ai64.c b/src/include/drv/gsc16ai64.c index 8a6bbcf6c8427de785a792858efdc9fb1463b9cc..9ad3f6d623c356ff2b08a3c724728a56e2ddde74 100644 --- a/src/include/drv/gsc16ai64.c +++ b/src/include/drv/gsc16ai64.c @@ -129,6 +129,7 @@ gsc16ai64Init( CDS_HARDWARE* pHardware, struct pci_dev* adcdev ) pHardware->pci_adc[ devNum ] = (volatile int *)pci_alloc_consistent( adcdev, 0x2000, &adc_dma_handle[ devNum ] ); pHardware->adcType[ devNum ] = GSC_16AI64SSA; + pHardware->adcDuoToneDivisor[ devNum ] = 1; pHardware->adcInstance[ devNum ] = pHardware->card_count[ GSC_16AI64SSA ]; pHardware->card_count[ GSC_16AI64SSA ] ++; pHardware->adcChannels[ devNum ] = GSAI_CHAN_COUNT; diff --git a/src/include/drv/gsc16ao16.c b/src/include/drv/gsc16ao16.c index 29874e12b7c259209d16fcb2cb5b1172c302b1cc..9b680402c313dc77f8a04589f200a391d7f46551 100644 --- a/src/include/drv/gsc16ao16.c +++ b/src/include/drv/gsc16ao16.c @@ -85,6 +85,7 @@ gsc16ao16Init( CDS_HARDWARE* pHardware, struct pci_dev* dacdev ) (volatile int *)pci_alloc_consistent( dacdev, 0x200, &dac_dma_handle[ devNum ] ); pHardware->dacAcr[ devNum ] = (int)( _dacPtr[ devNum ]->ASSC ); pHardware->dacType[ devNum ] = GSC_16AO16; + pHardware->dacDuoToneMultiplier[ devNum ] = 1; pHardware->dacCount++; pHardware->dacInstance[ devNum ] = pHardware->card_count[ GSC_16AO16 ]; pHardware->card_count[ GSC_16AO16 ] ++; diff --git a/src/include/drv/gsc18ai32.c b/src/include/drv/gsc18ai32.c index 8beb3e6ed18c5fd56df7eacb6c6be5aa0a6b8a3f..3dadefaf82d814a62b143598c9680ecda33588f3 100644 --- a/src/include/drv/gsc18ai32.c +++ b/src/include/drv/gsc18ai32.c @@ -141,6 +141,7 @@ gsc18ai32Init( CDS_HARDWARE* pHardware, struct pci_dev* adcdev ) pHardware->pci_adc[ devNum ] = (volatile int *)pci_alloc_consistent( adcdev, 0x2000, &adc_dma_handle[ devNum ] ); pHardware->adcType[ devNum ] = GSC_18AI32SSC1M; + pHardware->adcDuoToneDivisor[ devNum ] = 4; pHardware->adcInstance[ devNum ] = pHardware->card_count[ GSC_18AI32SSC1M ]; pHardware->card_count[ GSC_18AI32SSC1M ] ++; pHardware->adcConfig[ devNum ] |= autocal; diff --git a/src/include/drv/gsc18ai64.c b/src/include/drv/gsc18ai64.c index 6f501b2f7dce47b4609542a504f7c33996d02dad..620bbed021ecbbaac938f233caab3f85b7043671 100644 --- a/src/include/drv/gsc18ai64.c +++ b/src/include/drv/gsc18ai64.c @@ -133,6 +133,7 @@ gsc18ai64Init( CDS_HARDWARE* pHardware, struct pci_dev* adcdev ) pHardware->pci_adc[ devNum ] = (volatile int *)pci_alloc_consistent( adcdev, 0x2000, &adc_dma_handle[ devNum ] ); pHardware->adcType[ devNum ] = GSC_18AI64SSC; + pHardware->adcDuoToneDivisor[ devNum ] = 4; pHardware->adcInstance[ devNum ] = pHardware->card_count[ GSC_18AI64SSC ]; pHardware->card_count[ GSC_18AI64SSC ] ++; pHardware->adcConfig[ devNum ] = adc18Ptr->ASSC; diff --git a/src/include/drv/gsc18ao8.c b/src/include/drv/gsc18ao8.c index 0eceb147a42c25669b295633abd804fb6b14c0d7..f4ac31e569cc42fa86d795715753ff612e3f7e5f 100644 --- a/src/include/drv/gsc18ao8.c +++ b/src/include/drv/gsc18ao8.c @@ -122,6 +122,7 @@ gsc18ao8Init( CDS_HARDWARE* pHardware, struct pci_dev* dacdev ) (volatile int *)pci_alloc_consistent( dacdev, 0x200, &dac_dma_handle[ devNum ] ); pHardware->dacAcr[ devNum ] |= ((int)( dac18bitPtr->ASY_CONFIG ) & DAC_ACR_MASK); pHardware->dacType[ devNum ] = GSC_18AO8; + pHardware->dacDuoToneMultiplier[ devNum ] = 4; pHardware->dacCount++; pHardware->dacInstance[ devNum ] = pHardware->card_count[ GSC_18AO8 ]; pHardware->card_count[ GSC_18AO8 ] ++; diff --git a/src/include/drv/gsc20ao8.c b/src/include/drv/gsc20ao8.c index 436a8a422fc365f2729e4c5d8d7873e48d7bcded..54a6d4f5212fd1f72511089277c2a72f509a764f 100644 --- a/src/include/drv/gsc20ao8.c +++ b/src/include/drv/gsc20ao8.c @@ -141,6 +141,7 @@ gsc20ao8Init( CDS_HARDWARE* pHardware, struct pci_dev* dacdev ) // Return the device type to main code. pHardware->dacType[ devNum ] = GSC_20AO8; + pHardware->dacDuoToneMultiplier[ devNum ] = 8; pHardware->dacCount++; pHardware->dacInstance[ devNum ] = pHardware->card_count[ GSC_20AO8 ]; pHardware->card_count[ GSC_20AO8 ] ++; diff --git a/src/include/drv/iop_dac_functions.c b/src/include/drv/iop_dac_functions.c index a219399201cb793f059106e9d66cf8a7cd2646fb..72d6b19216fdffc8043760605d065809989ec609 100644 --- a/src/include/drv/iop_dac_functions.c +++ b/src/include/drv/iop_dac_functions.c @@ -163,7 +163,8 @@ iop_dac_write( ) if ( ( dt_diag.dacDuoEnable ) && ( chan == ( num_outs - 1 ) ) && ( card == 0 ) ) { - dac_out = adcinfo.adcData[ 0 ][ ADC_DUOTONE_CHAN ]; + dac_out = adcinfo.adcData[ 0 ][ ADC_DUOTONE_CHAN ] + * cdsPciModules.dacDuoToneMultiplier[0] / cdsPciModules.adcDuoToneDivisor[0]; } // Code below is only for use in DAQ test system. #ifdef DIAG_TEST