There is thus a trade-off. If the software does not issue a channel advance then it takes one external pulse to start the system counting. If the software does issue a channel advance, then the module starts counting immediately, which leads to "hot" first pixels.
It was decided to make the behavior be configurable in the startup script, so that users can choose the behavior that best meets their needs.
An additional argument was added to the STR7201Config command. The new syntax is:# STR7201Config(int card, int maxSignals, int maxChans, # int 1=enable internal 25MHZ clock, # int 1=enable initial software channel advance in MCS external advance mode)By setting the last argument to 1 a software channel advance will be issued when acquisition starts. Setting the argument to 0 or omitting it will lead to no software channel advance.
This new release has the following enhancements:
This new release has the following enhancements:
The device support for the ICB modules is provided in four main files:
devIcbMpf.cc This file provides support for the ao, mbbo, ai and mbbi records for all ICB modules. It knows nothing about any specific module, it simply passes messages to MPF with a parameter code and value.
icbServer.cc This is the MPF server software for the ADC, amplifier and HVPS.
icbTcaServer.cc This is the MPF server software for the TCA.
icbDspServer.cc This is the MPF server software for the 9660 digital signal processor (DSP)
Each of the MPF servers can control any number of ICB modules of the specified type. Thus, a single icbServer can control any number of ADCs, amplifiers and HVPS units, a single icbTcaServer can control any number of TCA modules, etc. On the other hand it is also possible to use multiple MPF servers when talking to multiple ICB modules of the same family. The decision as to when to use more than one MPF servers is one of performance. This decision is made in the initialization commands in the vxWorks startup file. Each MPF server is synchronous, meaning that it must wait for a reply from the AIM before processing the next message. When using multiple AIMs, for example with a multi-element detector, it can make sense to use multiple MPF ICB servers so that some communication can be done in parallel. On the other hand, the ICB communications are typically low bandwidth and a single MPF server will often suffice.
The following lines must be added to the vxWorks startup file. Note that the lines which create MPF servers are new to this release, and the lines which load the databases must be modified for this release.
# Initialize local MPF connection routerInit localMessageRouterStart(0) # Create AIM MCA server, load MCA record # AIMConfig(mpfServer, ethernet_address, port, maxChans, # maxSignals, maxSequences, ethernetDevice, queueSize) AIMConfig("AIM1/1", 0x59e, 1, 2048, 1, 4, "dc0", 100) dbLoadRecords("share/mcaApp/Db/mca.db", "P=13LAB:,M=aim_adc1,DTYPE=MPF MCA,INP=#C0 S0 @AIM1/1,NCHAN=2048") # Create ICB server for ADC, amplifier and HVPS # picbServer = icbConfig(icbServer, maxModules, icbAddress, queueSize) # This creates the ICB server and allocates configures the first module, module 0. # Additional modules are added to this server with icbAddModule(). picbServer = icbConfig("icb/1", 10, "NI59E:5", 100) # In the dbLoadRecords commands CARD=(0,1) for (local/remote), SERVER=icbServer name from icbConfig, # ADDR=module number from icbConfig() or icbAddModule(). dbLoadRecords "share/mcaApp/Db/icb_adc.db", "P=13LAB:,ADC=adc1,CARD=0,SERVER=icb/1,ADDR=0" #icbAddModule(picbServer, module, icbAddress) icbAddModule(picbServer, 1, "NI59E:3") dbLoadRecords "share/mcaApp/Db/icb_amp.db", "P=13LAB:,AMP=amp1,CARD=0,SERVER=icb/1,ADDR=1" icbAddModule(picbServer, 2, "NI59E:2") dbLoadRecords "share/mcaApp/Db/icb_hvps.db","P=13LAB:,HVPS=hvps1,CARD=0,SERVER=icb/1,ADDR=2, LIMIT=1000" # This creates the TCA server and allocates configures the first module, module 0. # Additional modules are added to this server with icbTcaAddModule(). # ptcaServer = tcaConfig(tcaServer, maxModules, icbAddress, queueSize) icbTcaConfig("icbTca/1", 1, "NI59E:8", 100) dbLoadRecords "share/mcaApp/Db/icb_tca.db", "P=13LAB:,TCA=tca1,MCA=aim_adc2,CARD=0,SERVER=icbTca/1,ADDR=0"
# Struck MCS as 32-channel multi-element detector # STR7201Setup(maxCards, baseAddress, interruptVector, interruptLevel) STR7201Setup(1,0xA0000000,220,6)
# The ch1RefEnable parameter to STR7201Config is new. 1=enable internal 25MHz clock on first input. # STR7201Config(card, maxSignals, maxChans, ch1RefEnable) STR7201Config(0, 32, 2048, 1) dbLoadRecords("share/mcaApp/Db/Struck32.db","P=13LAB:str:") dbLoadTemplate("Struck32.template") # Generic CAMAC record #dbLoadRecords("share/camacApp/Db/generic_camac.db","P=13LAB:,R=camac1,SIZE=2048") ### Scalers: Joerger VSC8/16 dbLoadRecords("share/stdApp/Db/Jscaler.db","P=13LAB:,S=scaler1,C=0") ### Scalers: Struck/SIS as simple scaler dbLoadRecords("share/mcaApp/Db/STR7201scaler.db","P=13LAB:,S=scaler2,C=0")
Here is an example Struck32.template:
file share/mcaApp/Db/simple_mca.db { pattern {P, M, DTYP, INP, PREC, CHANS} {13LAB:str: mca1, "Struck STR7201 MCS", "#C0 S0", 3, 2048} {13LAB:str: mca2, "Struck STR7201 MCS", "#C0 S1", 3, 2048} {13LAB:str: mca3, "Struck STR7201 MCS", "#C0 S2", 3, 2048} {13LAB:str: mca4, "Struck STR7201 MCS", "#C0 S3", 3, 2048} {13LAB:str: mca5, "Struck STR7201 MCS", "#C0 S4", 3, 2048} {13LAB:str: mca6, "Struck STR7201 MCS", "#C0 S5", 3, 2048} {13LAB:str: mca7, "Struck STR7201 MCS", "#C0 S6", 3, 2048} {13LAB:str: mca8, "Struck STR7201 MCS", "#C0 S7", 3, 2048} {13LAB:str: mca9, "Struck STR7201 MCS", "#C0 S8", 3, 2048}^M {13LAB:str: mca10, "Struck STR7201 MCS", "#C0 S9", 3, 2048}^M {13LAB:str: mca11, "Struck STR7201 MCS", "#C0 S10", 3, 2048}^M {13LAB:str: mca12, "Struck STR7201 MCS", "#C0 S11", 3, 2048}^M {13LAB:str: mca13, "Struck STR7201 MCS", "#C0 S12", 3, 2048}^M {13LAB:str: mca14, "Struck STR7201 MCS", "#C0 S13", 3, 2048}^M {13LAB:str: mca15, "Struck STR7201 MCS", "#C0 S14", 3, 2048}^M {13LAB:str: mca16, "Struck STR7201 MCS", "#C0 S15", 3, 2048}^M {13LAB:str: mca17, "Struck STR7201 MCS", "#C0 S16", 3, 2048}^M {13LAB:str: mca18, "Struck STR7201 MCS", "#C0 S17", 3, 2048}^M {13LAB:str: mca19, "Struck STR7201 MCS", "#C0 S18", 3, 2048}^M {13LAB:str: mca20, "Struck STR7201 MCS", "#C0 S19", 3, 2048}^M {13LAB:str: mca21, "Struck STR7201 MCS", "#C0 S20", 3, 2048}^M {13LAB:str: mca22, "Struck STR7201 MCS", "#C0 S21", 3, 2048}^M {13LAB:str: mca23, "Struck STR7201 MCS", "#C0 S22", 3, 2048}^M {13LAB:str: mca24, "Struck STR7201 MCS", "#C0 S23", 3, 2048}^M {13LAB:str: mca25, "Struck STR7201 MCS", "#C0 S24", 3, 2048}^M {13LAB:str: mca26, "Struck STR7201 MCS", "#C0 S25", 3, 2048}^M {13LAB:str: mca27, "Struck STR7201 MCS", "#C0 S26", 3, 2048}^M {13LAB:str: mca28, "Struck STR7201 MCS", "#C0 S27", 3, 2048}^M {13LAB:str: mca29, "Struck STR7201 MCS", "#C0 S28", 3, 2048}^M {13LAB:str: mca30, "Struck STR7201 MCS", "#C0 S29", 3, 2048}^M {13LAB:str: mca31, "Struck STR7201 MCS", "#C0 S30", 3, 2048}^M {13LAB:str: mca32, "Struck STR7201 MCS", "#C0 S31", 3, 2048}^M }
The following lines should be added to Makefile.Vx in the application directory. This example contains the lines to build the latest versions of both mcaApp and ipApp.
include $(SHARE)/mcaApp/src/mcaLIBOBJS LIBOBJS += $(MCALIBOBJS) include $(SHARE)/ipApp/src/ipLIBOBJS LIBOBJS += $(IPLIBOBJS) include $(SHARE)/camacApp/src/camacLIBOBJS LIBOBJS += $(CAMACLIBOBJS) include $(SHARE)/ipApp/src/ipMpfServerLIBOBJS include $(SHARE)/mcaApp/src/mcaMpfServerLIBOBJS LIBOBJS += $(MCAMPFSERVERLIBOBJS) PROD += mpfServLib include $(TOP)/config/RULES.Vx #---------------------------------------- # ADD RULES AFTER THIS LINE mpfServLib: $(IPMPFSERVERLIBOBJS) $(LINK.c) $@ $(IPMPFSERVERLIBOBJS)
The Struck STR7201/SIS 380x device support for the scaler record is improved so that acquisition terminates within 0.01 seconds of the preset time. The device support for the MCA record and scaler record are now compatible, so that it is possible to have scaler and MCA records which communicate with the device loaded in the IOC simultaneously. The only restriction is that the only one record type or the other should be communicating with the hardware at any one time. The Struck8.db database was modified so that presets work correctly.
A serious bug was fixed in drvSTR7201.c. Previously it was possible for multiple vxWorks tasks, including the interrupt handler, to be talking to the hardware simultaneously. This could cause bus errors when reading the FIFO and other nasty problems. A semaphore was added and interrupts were disabled at appropriate times to prevent such conflicts.
Changed the task priority of the nmc_status_dispatch and nmc_inquiry tasks in nmc_comm_subs_1.c to 100 from 50, so that they would be lower priority than tnetTask.
Added support for the Canberra 9660 DSP module. This module uses the devIcbMpf device support (same as the AIM MCA device support) and an MPF server, icbDspServer.cc. The device support uses standard EPICS records (ao, mbbo, ai, mbbi).
This release of mcaApp is intended primarily to improve performance with the Canberra AIM MCA hardware. The main enhancements are:
To make the low-level AIM support routines able to send commands to multiple AIMs in parallel, i.e. without waiting for the response from one AIM before sending a command to another. This is necessary to improve the performance of systems with multiple AIMs being used for multi-element detectors.
To make the device support for the AIM be "asynchronous". In previous versions the AIM device support was "synchronous", meaning that the MCA record waited for a response from the AIM before returning. Since the AIM can take 50-100 msec to respond to some commands, this was poor EPICS programming practice. It would cause the EPICS scan tasks to wait for extended periods of time, particularly if many MCA records were being used.
To improve the performance of the AIM device support when used with multiplexors, i.e. multiple MCA records per AIM ADC port.
To modify the multi-element detector databases to process MCA records in parallel, taking advantage of changes 1) and 2) above.
One result of these changes is that the overhead with multielement detector systems will be reduced proportionally by the number of AIMs in the system, e.g. a system with 4 AIMs should have 4 times less overhead than in previous versions. The overhead time to collect 13 spectra of 2048 channels from a detector with 4 AIMs should now be about 0.25 seconds.
In the previous versions of the low-level AIM routines (nmc_comm_subs_1.c, nmc_comm_subs_2.c) there was a single system-wide interlock and message response queue for AIM communication. Once a message was sent to any AIM no further messages could be sent to any AIM until the response from the first AIM was received. This was a serious performance limitation when communicating with multiple AIMs. It is much more efficient to have separate interlocks and message response queues for each AIM, rather than a single one per IOC. The low-level AIM routines were re-written to implement this more efficient model which permits simultaneous communication with multiple AIM modules.
Previous versions the AIM device support was "synchronous", meaning that the MCA record waited for a response from the AIM before returning. Since the AIM can take 50-100 msec to respond to some commands, this was poor EPICS programming practice. It would cause the EPICS scan tasks to wait for extended periods of time, particularly if many MCA records were being used. However, the low-level AIM routines are necessarily synchronous since multiple transactions with the AIM can be required to implement a single high-level function (e.g. "erase").
What is needed, therefore, is a separate vxWorks task for each AIM or AIM port. The record should call the AIM device support, which in turn sends a message to the appropriate task and then returns immediately. The task communicates synchronously with the AIM, and then issues a callback to record support when the AIM communication is complete.
The solution to this problem turned out to be quite simple, since this is exactly what the Message Passing Facility, MPF is intended to do. In fact there was already MPF device support for the MCA record for the Acromag IP330 ADC when used as a waveform digitizer. All that needed to be done was to take this device support (devMcaIp330.cc) and convert it to a general MCA device support interface. This layer does not need to know anything about the particular MCA device, its role is simply to pass messages from the MCA record to an MPF server. The new file devMcaMpf.cc implements this device-independent layer. All of the device dependent code is now in the specific MPF server.
For the Acromag IP330 ADC the existing Ip330SweepServer.cc was rewritten slightly to handle the more general messages from devMcaMpf.cc. Ip330Sweep.cc was rewritten slightly to handle live-time as well as real-time messages. This new version of ip330App must be used when upgrading to this release of mcaApp.
A new MPF server, mcaAIMServer.cc was written to communicate with AIM modules. There is one such server per AIM ADC port, e.g. up to two servers per AIM. This server is basically just a rewrite of the code which was previously in devMCA_AIM.c. The flow of control for communication with the AIM is now:
mcaRecord processes, calling a function in devMcaMpf
devMcaMpf sends a message to mcaAIMServer and returns to immediately to mcaRecord. mcaRecord returns immediately to EPICS.
mcaAIMServer, which runs as a separate vxWorks task, sends one or more messages to the AIM and waits for the replies.
When the replies are all received mcaAIMServer sends a message back to devMcaMpf.
devmcaMpf issues a callback to mcaRecord, which calls devMcaMpf again to complete the operation.
This scheme properly implements asynchronous record processing, so that AIM communication no longer causes the EPICS scan tasks to wait.
mcaAIMServer.cc implements several optimizations to improve performance when used with multiplexors, typically used with multielement detectors. When a multiplexor is used there are multiple "signals" on a single AIM ADC port or mcaAIMServer. The following optimizations are now implemented:
If an Erase command is sent for signal 0 then the AIM memory for all of the signals is erased. This is done in a single message to the AIM. This is significantly faster than sending multiple messages to erase smaller blocks of AIM memory. Multielement detector databases take advantage of this optimization by only sending Erase commands for the first signal (0) on each port. It is not necessary to send erase commands for the other signals, because the memory will be erased when signal 0 is erased. The elapsed real time, elapsed live time and elapsed total counts are common to all signals on each port, and these will also be reset when an erase is sent to signal 0.
The results of Read Status commands (elapsed live time, elapsed real time, elapsed total counts, and acquiring status) are cached in the mcaAIMServer object. If a Read Status command is received by mcaAIMServer then this will result in a network message being sent to the AIM only if:
The Read Status command is for signal 0
or
The time since the most recent Read Status command was sent to the AIM is more than 0.1 seconds
This optimization results in significantly fewer network messages being sent to the AIM, since the status for all signals is typically read in rapid succession, and the cached value will generally be used for all but signal 0.
There was a problem in previous versions of drvSTR7201.c for the prescale feature of the SIS 380x. The internal prescale counter was not correctly reset when the prescale value was changed. This could be a serious problem when changing from a large prescale value to a small prescale value, since the first dwell period after the change could require many more channel advance pulses (internal or external) than it should. SIS has provided additional information on how to properly program the prescaler, and the problem is now fixed.
A new field, .ERST (ERase/STart) was added to the mcaRecord. Writing a 1 to this field causes the record to execute an Erase and a Start in a single operation, rather than the two operations required if the .ERAS and .STRT fields are written to separately. Adding this field has two beneficial effects:
The init_record
routine was changed to set flags
which cause all of fields of interest to device support (.PRTM,
.PLTM, .NUSE, etc.) to be sent to device support the first time
the record processes.
In principle all databases which create MCA records should now
set PINI="YES" so that the MCA record processes once at iocInit
and all of these values are sent to device support at that time.
However this does not work for MPF devices yet (AIM, IP330)
because at record initialization the MPF server has typically not yet connected
and it gets the message passing out of sync if PINI is YES. For now we do not
set PINI=YES in the MCA databases.
The MPF device support synchronizes the device
with the record when the MPF server connects. Furthermore the record will
synchronize again the first time the record processes.
A logic bug was fixed which caused the record to misbehave if the .READ field was set while a Read callback was pending.
mca.db was simplified with the removal of a fanout and swait record because EraseStart now uses the .ERST field in the MCA record. The current version is mca_5.3.db.
16element.db was modified as follows:
A new database, simple_mca.db was created. It replaces simple_mca_aim.db and simple_mca_struck.db. Template files which call simple_mca.db must now pass DTYP, INP, and PREC.
Because the AIM device support now requires MPF there are some changes required in building applications which use the AIM. When building an application directory <myApp>/src in the past it was only necessary to include in Makefile.Vx the lines:
include $(SHARE)/mcaApp/src/mcaLIBOBJS LIBOBJS += $(MCALIBOBJS)
and in <APP>Include.dbd the line
include "mcaShare.dbd"
Because MPF can pass messages across the network, including across the backplane to an auxilliary CPU, the user has choices as to where to actually run the mcaAIMServer MPF server. I recommend running it locally on the same CPU which is running the EPICS MCA record, since this will minimize the MPF communications overhead. In this case it is necessary to load the basic MPF server code and the mcaAimServer code onto this CPU. This may not be currently happening if the IOC is set up to run the MPF server code only on an auxilliary CPU. The solution I recommend is to build a separate MPF server library in <myApp>/src by adding the following lines to Makefile.Vx
include $(SHARE)/ipApp/src/mpfServerLIBOBJS include $(SHARE)/mcaApp/src/mpfServerLIBOBJS #---------------------------------------- # ADD RULES AFTER THIS LINE mpfServLib: $(MPFSERVERLIBOBJS) $(LINK.c) $@ $(MPFSERVERLIBOBJS)
This works by looking at the files ipApp/mpfServerLIBOBJS and mcaApp/mpfServerLIBOBJS to make a list of all the object files required to build mpfServerLib. Users may need to get the latest version of ipApp from Tim Mooney in order to get mpfServerLIBOBJS. If mpfServerLib is built this way and is loaded on a CPU which does not have IP slots (e.g. MV167 or PPC) then there is some unused code, but the memory cost is not large.
There is a problem with the current version of DevMpf.cc in the MPF distribution. DevMpf prevents a record from sending multiple messages to device support during one record processing. This problem will be fixed in the next release of MPF. Meanwhile in order for the MCA record to work with MPF the following lines must be deleted from DevMpf::read_write in DevMpf.cc.
if(pcommon->pact==TRUE && pdevMpf->replyMessage==0) { if(DevMpfDebug) epicsPrintf("%s PACT true and no reply message\n"); recGblSetSevr(pcommon,COMM_ALARM,INVALID_ALARM); return(MPF_NoConvert); }
The vxWorks startup file must be changed to use the new AIM device support code.
The following lines should be added near the beginning, after loading iocCore and all of your other support libraries:
# Initialize local MPF connection ld < mpfServLib routerInit localMessageRouterStart(0)
Note that some or all of these lines may already exist in your startup file, depending upon whether you are currently running MPF at all, and/or are running a local MPF server.
The following lines show the global variables to turn on debugging at various levels. aimDebug turns on debugging for the low level AIM routines, etc. Setting these flags to higher numbers (1-10) turns on increasingly more verbose debugging messages.
mcaRecordDebug = 0 devMcaMpfDebug = 0 mcaAIMServerDebug = 0 aimDebug = 0
The AIMSetup() command which was previously used to indicate the maximum number of AIMs in a system is no longer used. Allocation of structures for each AIM now happens in AIMConfig when the mcaAIMServer object is created.
The format of the AIMConfig() command has changed. The syntax is now:
### AIMConfig(serverName, ethernetAddress, port, maxChans, maxSignals, ### maxSequences, ethernetDevice, queueSize) AIMConfig("AIM1/1", 0x6E6, 1, 2048, 1, 1, "ei0", 100) AIMConfig("AIM1/2", 0x6E6, 2, 2048, 4, 1, "ei0", 100)
serverName
,
the MPF server name, is arbitrary, it just must be the same in
the AIMConfig and dbLoadRecords commands. The name of the vxWorks
task will be the name of the MPF server with the letter
"t" in front of it, e.g. tAIM1/1
in this case.
ethernetAddress
is the low order 16 bits of the AIM Ethernet address, which is
printed on the front of the AIM.
port
is the
AIM ADC port for this server, 1 or 2.
maxChans, maxSignals
and
maxSequences
are
the maximum number of channels, signals (used for multiplexors
and Canberra MCS units) and sequences (used for time-resolved
spectroscopy). The amount of memory required in the AIM is maxChans*maxSignals*maxSequences*4
bytes.
ethernetDevice
is the name of the vxWorks Ethernet device for the network with
this AIM. This is typically "ei0" for the Motorola 68K
CPUs and "dc0" for the Motorola PowerPC CPUs.
queueSize
is
the size of the MPF message queue for this server. 100 should be
plenty.
The format of the dbLoadRecords command has also changed:
dbLoadRecords("share/mcaApp/Db/mca.db", "P=13IDC:,M=aim_adc1,DTYPE=MPF MCA,INP=#C0 S0 @AIM1/1,NCHAN=2048") dbLoadRecords("share/mcaApp/Db/mca.db", "P=13IDC:,M=aim_mcs1,DTYPE=MPF MCA,INP=#C0 S0 @AIM1/2,NCHAN=2048")
The DTYPE field is now "MPF MCA" rather than "Canberra AIM MCA". The "card" (#Cn) is now the identification number of the MPF server (e.g. 0=local MPF server, 1=remote MPF server) rather than a number specific to each AIM. The parm field is now @serverName to specify the MPF server for this AIM.
Example multielement template file and command file.
The following is an example of a vxWorks command file script to load everything for the GSECARS 16 element detector which uses 2 AIMs with multiplexors. This file is invoked with "<16element.cmd".
# AIMConfig(mpfServer, ethernet_address, port, maxChans, # maxSignals, maxSequences, ethernetDevice, queueSize) AIMConfig("AIM1/1", 0x8d7, 1, 4096, 4, 1, "ei0", 100) AIMConfig("AIM1/2", 0x8d7, 2, 4096, 4, 1, "ei0", 100) AIMConfig("AIM2/1", 0x3ec, 1, 4096, 4, 1, "ei0", 100) AIMConfig("AIM2/2", 0x3ec, 2, 4096, 4, 1, "ei0", 100) dbLoadRecords("share/mcaApp/Db/16element.db","P=13GE1:med:") dbLoadTemplate("16element.template") ### Struck/SIS as simple scaler for ICR STR7201Setup(1,0xA0000000,220,6) STR7201Config(0, 16, 100) dbLoadRecords("share/mcaApp/Db/STR7201scaler.db","P=13GE1:med:, S=scaler1, C=0")
The following is the 16element.template file which the above file loads:
file share/mcaApp/Db/simple_mca.db { pattern { P, M, DTYP, INP PREC, CHANS} {13GE1:med: mca1 "MPF MCA", "#C0 S0 @AIM1/1", 3, 2048} {13GE1:med: mca2 "MPF MCA", "#C0 S1 @AIM1/1", 3, 2048} {13GE1:med: mca3 "MPF MCA", "#C0 S2 @AIM1/1", 3, 2048} {13GE1:med: mca4 "MPF MCA", "#C0 S3 @AIM1/1", 3, 2048} {13GE1:med: mca5 "MPF MCA", "#C0 S0 @AIM1/2", 3, 2048} {13GE1:med: mca6 "MPF MCA", "#C0 S1 @AIM1/2", 3, 2048} {13GE1:med: mca7 "MPF MCA", "#C0 S2 @AIM1/2", 3, 2048} {13GE1:med: mca8 "MPF MCA", "#C0 S3 @AIM1/2", 3, 2048} {13GE1:med: mca9 "MPF MCA", "#C0 S0 @AIM2/1", 3, 2048} {13GE1:med: mca10 "MPF MCA", "#C0 S1 @AIM2/1", 3, 2048} {13GE1:med: mca11 "MPF MCA", "#C0 S2 @AIM2/1", 3, 2048} {13GE1:med: mca12 "MPF MCA", "#C0 S3 @AIM2/1", 3, 2048} {13GE1:med: mca13 "MPF MCA", "#C0 S0 @AIM2/2", 3, 2048} {13GE1:med: mca14 "MPF MCA", "#C0 S1 @AIM2/2", 3, 2048} {13GE1:med: mca15 "MPF MCA", "#C0 S2 @AIM2/2", 3, 2048} {13GE1:med: mca16 "MPF MCA", "#C0 S3 @AIM2/2", 3, 2048} }
file share/mcaApp/Db/icb_amp.db { pattern {P, AMP, ICB} {13GE1:med: amp1 NI8D7:1} {13GE1:med: amp2 NI8D7:2} {13GE1:med: amp3 NI8D7:3} {13GE1:med: amp4 NI8D7:4} {13GE1:med: amp5 NI8D7:5} {13GE1:med: amp6 NI8D7:6} {13GE1:med: amp7 NI8D7:8} {13GE1:med: amp8 NI8D7:9} {13GE1:med: amp9 NI3EC:1} {13GE1:med: amp10 NI3EC:2} {13GE1:med: amp11 NI3EC:3} {13GE1:med: amp12 NI3EC:4} {13GE1:med: amp13 NI3EC:5} {13GE1:med: amp14 NI3EC:6} {13GE1:med: amp15 NI3EC:8} {13GE1:med: amp16 NI3EC:9} }
file share/mcaApp/Db/icb_adc.db { pattern {P, ADC, ICB} {13GE1:med: adc1 NI8D7:B} {13GE1:med: adc2 NI8D7:0} {13GE1:med: adc3 NI3EC:B} {13GE1:med: adc4 NI3EC:7} } file share/mcaApp/Db/icb_hvps.db { pattern {P, HVPS, ICB} {13GE1:med: hvps1 NI3EC:A} }
drvSTR7201.c for the Struck 7201 and SIS 380x had some serious problems:
Tim Mooney found and fixed a problem in the ICB routines which was causing crashes if an unknown ICB module, such as the TCA or DSP was present.
Made changes to the AIM software to allow it to run on the PowerPC.
Improved performance of the erase command in mcaRecord.c by not sending a read_data request to device support after an erase, just clear the array in the record and post a monitor on the VAL field.
Previously the
nmc_acqu_setelapsed
command (in nmc_user_subs_2.c)
always did the following:
nmc_acqu_setelapsed
cannot set the elapsed times if the AIM is acquiring. However,
this method has a lot of extra overhead if the AIM is not
acquiring.
Moved the logic into device support. Only turn off acquisition if it is determined to be on by the ACQG field in the record. This improves performance. It also improves accuracy if the AIM is acquiring, because the erase and setelapsed will now both be done with acquisition off.
This documents the changes made to mcaApp since synApps_R3.13.1.1. The changes have been substantial, and users must make a number of simultaneous changes in order to use the new release:
The changes to mcaApp are described below in roughly decreasing order of significance.
The databases mca.db, 3element.db and 13element.db have been changed significantly. A new database, Struck8.db has been added to support 8 channel data acquisition using the Struck ST7201 or SIS 380x multichannel scaler.
There MEDM .adl files (mca.adl, mca_small.adl, 13element.adl, etc.) have been changed to reflect these changes in the databases.
dbLoadRecords("share/mcaApp/Db/mca.db", "P=13BMD:, M=aim_adc1, DTYPE=Canberra AIM MCA, CARD=0, SIGNAL=0, NCHAN=2048")
with
dbLoadRecords("share/mcaApp/Db/mca.db", "P=13BMD:, M=aim_adc1, DTYPE=Canberra AIM MCA, INP=#C0 S0, NCHAN=2048")
For the Struck/SIS replace lines like:
dbLoadRecords("share/mcaApp/Db/mca.db", "P=13LAB:, M=mca_str2, DTYPE=Struck STR7201 MCS, NCHAN=1024, CARD=0, SIGNAL=1")
with
dbLoadRecords("share/mcaApp/Db/mca.db", "P=13LAB:, M=mca_str2, DTYPE=Struck STR7201 MCS, NCHAN=1024, INP=#C0 S1")
For the Ip330Sweep use lines like
dbLoadRecords("share/mcaApp/Db/mca_ip330.db", "P=13LAB:, M=mip330_1, DTYPE=ip330Sweep, NCHAN=2048, INP=#C1 S0 @c-Ip330Sweep")
grecord(bo,"$(P)$(M)Start") { field(OMSL,"closed_loop") field(DOL,"1") field(OUT,"$(P)$(M).STRT CA MS") field(FLNK,"$(P)$(M)SetClientWait") } # These records are to synchronize with IDL or another client grecord(bo,"$(P)$(M)EnableWait") { field(ZNAM,"Disable") field(ONAM,"Enable") } grecord(bo,"$(P)$(M)SetClientWait") { field(DISV,"0") field(SDIS,"$(P)$(M)EnableWait NPP NMS") field(OMSL,"closed_loop") field(DOL,"1") field(OUT,"$(P)$(M)ClientWait PP MS") } grecord(busy,"$(P)$(M)ClientWait") {}
The logic behind these records is quite simple. EnableWait is used to enable or disable waiting for ClientWait. It is disabled at iocInit, and can be enabled/disabled from mcaSetup.adl. Each time acquisition is started via the database SetClientWait is processed. If EnableWait is enabled, then ClientWait changes to 1. If a scan record detector trigger was what caused acquisition to start, then the scan will wait until ClientWait goes back to 0 before it moves the positioners to the next point. IDL or another client can read the data from the MCA record, write it to disk (or do anything else with it) and then write 0 to ClientWait when it is OK for the scan to proceed. The IDL procedures EPICS_MCA::WRITE_FILE and EPICS_MED::WRITE_FILE have been changed to set ClientWait to 0 after the data are written to disk. There are two minor limitations of this synchronization mechanism:
New device support has been added for the Acromag IP-330 ADC acting as a waveform recorder/transient digitizer, i.e. the MCA spectrum contains voltage as a function of time. This device support allows one to capture up to 32 waveforms nearly simultaneously. Times per point as short as 100 microseconds are possible with up to 6 waveforms. The device support and documentation is not in mcaApp, but rather in mpf/ip330App. This device support requires MPF. It can run either on a single CPU (e.g. MVME162 running both EPICS and MPF) or on a multiple CPU system (e.g. MVME167 running EPICS and MVME162 running MPF).