readoutscript name [-controllertype type] [-initscript path] [-rdolistcript path] [-onendscript path]
The readoutscript package provides a snit::type called readoutscript that can be used to source Tcl scripts to configure modules for readout. It can also be used to add commands to the stack during the readout. The idea is that the user can create an instance of the snit::type and then register it as a Tcl driver. It is the means by which drivers such as ACrdcXLM72, APpacXLM72, and ACAENV288 are intended to be used. The driver is generic and can be used in either the VMUSBReadout or CCUSBReadout programs.
The only required option is -controllertype
, whose
argument specifies whether the driver will be handling VMUSB or CCUSB
requests. The rest of the options are truly optional.
The -controllertype parameter is the only required option. Its argument,
type
, must be either "vmusb" or "ccusb". If neither
is provided, an error will occur.
The -initscript
option specifies the path to a Tcl
script that will be evaluated in the global scope. It is executed
at the startup of the slow controls server (i.e. at program
startup) and any time the user calls the init
from within the Readout program it is associated with. If this
option is not provided, it will be ignored.
While the script executes, the Globals::aController variable will refer to the VMUSB or CCUSB object managed by the Readout program. The object is either a cvmusb::CVMUSBusb or ccusb::CCCUSB object and has methods provided by the cvmusb or ccusb package, respectively.
The -rdolistscript
option specifies the path to a
Tcl script that will be evaluated in the global scope. In this
script, you should add stack commands to the
"Globals::aReadoutList" object, which is either a CCCUSBReadout or
CVMUSBReadout object provided by the cccusb or cvmusb package. The
commands that are added to the stack will be executed whenever the
associated trigger occurs.
While the script executes, the Globals::aReadoutList variable will refer to the VMUSB or CCUSB object managed by the Readout program. It can be manipulated using the methods provided in the cvmusbreadoutlist or cccusbreadoulist package.
The -onendscript
option specifies the path to a
Tcl script that will be evaluated in the global scope. It is
executed immediately after a run is ended. If this option is not
provided, it will be ignored.
While the script executes, the Globals::aController variable will refer to the VMUSB or CCUSB object managed by the Readout program. The object is either a cvmusb::CVMUSBusb or cccusb::CCCUSBusb object and has methods provided by the cvmusb or cccusb package, respectively.
Example 1. An example usage in VMUSBReadout
Consider that you are running VMUSBReadout and want to add control the configuration and readout of a module completely throw low-level scripts. To do so, you would specify all of the logic in a set of scripts. The code to configure the module for readout might be in a file called init.tcl, the code for specifying how to read the module out would be in a file called event.tcl, and the code to shutdown the module's readout mode would be in a file called end.tcl. You would start by creating a daqconfig.tcl that has the following contents.
lappend auto_path [file join $::env(DAQROOT) TclLibs]lappend auto_path $::env(DAQLIB) package require cvmusb package require cvmusbreadoutlist package require readoutscript
readoutscript mydriver -controllertype vmusb
mydriver configure -initscript [file join /path to init.tcl] mydriver configure -rdolistscript [file join /path to event.tcl] mydriver configure -onendscript [file join /path to end.tcl] addtcldriver mydriver
stack create evtStack stack config evtStack -modules [list mydriver] -trigger nim1
![]()
For the init.tcl file, the logic will be extremely simple. I am going to assume that there is only one register to write to put the device into a state that suitable for data taking. Of course this is absurd and a real example would require a bit more than writing one register. Here we assume that writing 1 to a register at address 0xa2020100 using A32 single data access (0x09) is sufficient. We will also check via a read that it got set appropriately.
set ctlr $::Globals::aController # write, read, and then check the value $ctlr vmeWrite16 0xa2020100 0x09 1 set newValue [$ctlr vmeRead16 0xa2020100 0x09] if {$newValue != 1} { puts "ERROR! Write did not successfully set the value in the module" }
Next we want read out the device when a trigger arrives. Let's assume that involves a block read with 34 transfers from address 0xa202000 and then a write to reset it. For the block read we need to use the 0x0b address modifier because the device is accessed using A32 addressing. We will also add some markers to bookend the data for easy identification. Here is what that would look like in the event.tcl file.
set stack $::Globals::aReadoutList $stack addMarker 0xabcd $stack addBlockRead32 0xa202000 0x0b 34 ;# 32 transfer BLT $stack addWrite32 0xa20200200 0x09 1 ; # clear the module for a new event $stack addMarker 0xbbcd
Finally, the end.tcl script is going to be used to take the device out of acquisition mode. Let's assume that this is accomplished in a manner that is opposite to what was done in init.tcl. So instead of writing a 1, we are going to write 0. Here is the end.tcl file:
set ctlr $::Globals::aController # write, read, and then check the value $ctlr vmeWrite16 0xa2020100 0x09 0 set newValue [$ctlr vmeRead16 0xa2020100 0x09] if {$newValue != 0} { puts "ERROR! Write did not successfully set the value in the module" }