Back Midas Rome Roody Rootana
  Midas DAQ System, Page 104 of 142  Not logged in ELOG logo
ID Date Author Topic Subject
  776   11 Jul 2011 Konstantin OlchanskiBug Fixmidas shared memory changes
> > > 2) the shared memory type used by an experiment is recorded in the file .SHM_TYPE.TXT.
> > > 3) the hostname of the computer where the ODB shared memory is meant to reside is now
> > > recorded in the file .SHM_HOST.TXT.


Because the mserver did not setup correct experiment name and path, POSIX shared memory did not work at all when used with the mserver. Fixed in mserver.c rev 5135


Sorry for the inconvenience,
K.O.
  775   10 Jul 2011 Konstantin OlchanskiBug Fixmidas shared memory changes
> > 2) the shared memory type used by an experiment is recorded in the file .SHM_TYPE.TXT.
> > 3) the hostname of the computer where the ODB shared memory is meant to reside is now
> > recorded in the file .SHM_HOST.TXT.

Due to a typo in src/system.c svn rev 5125, ss_shm_delete() did not work at all. This broke "odbedit -R", "odbedit -s 5000000" (to change ODB size), etc. 
Fixed in src/system.c svn rev 5134. (It is safe to update just tis one file to fix this problem).

Sorry for the inconvenience,
K.O.
  774   05 Jul 2011 Konstantin OlchanskiBug ReportMacOS network socket timeouts non-functional
It turns out that because of differences between select() syscall implementation between UNIX (MacOS, 
maybe BSD) and Linux,  network socket timeouts do not work.

This affects timeouts during run transitions (transition calls to dead clients do not timeout), maybe other 
places.

I am looking into fixing this. The main difficulty is with UNIX select() not updating the timeout parameter 
when it is interrupted by the MIDAS watchdog alarm signal. Linux select() subtracts the elapsed time from 
the timeout value and this code from system.c works correctly: while (1) { status = select(..., &timeout); if 
(status==0) break; } (value of timeout becomes smaller each time), while on MacOS it loops forever (value 
of timeout does not change).
K.O.
  773   05 Jul 2011 Konstantin OlchanskiInfomidas shared memory changes
> 2) the shared memory type used by an experiment is recorded in the file .SHM_TYPE.TXT.

An error with creating the file .SHM_TYPE.TXT was corrected in system.c svn rev 5125 - if file did not exist, it is 
created correctly, but MIDAS reports "cannot connect to ODB". Second try works correctly because the file exists 
now.

> 3) the hostname of the computer where the ODB shared memory is meant to reside is now
> recorded in the file .SHM_HOST.TXT.

This is causing problems on mobile computers where "hostname" changes all the time (i.e. set according to 
DHCP on whatever network happens to be connected).

If you run into this problem, keep deleting .SHM_HOST.TXT or use this workaround: disable the hostname check 
by making the file .SHM_HOST.TXT empty (zero length).

K.O.
  772   27 Jun 2011 Konstantin OlchanskiInfomlogger lock for runNNN.mid.gz files
By popular request, Stefan R. implemented a locking scheme for mlogger output files.

To use this function, set the mlogger ODB /Logger/Channels/NNN/Settings/Filename
to ".run%05dsub%05d.mid.gz" (note the leading dot).

In this mode, active output files will have a filename with a leading dot
(.run00001sub00001.mid.gz) while the file is being written to. After the file is
closed, it is renamed and the leading dot is removed.

To use this function with the lazylogger, please set ODB
"/Lazy/Foo/Settings/Filename format" to "run*.mid.gz,run*.xml" (note the leading
text "run"). Set "stay behind" to 0.

svn rev 5080 (or so, checking by Stefan R.)
K.O.
  771   27 Jun 2011 Konstantin OlchanskiInfomidas shared memory changes
A number of changes were made to the midas shared memory implementation for
Linux and MacOS:

1) SysV or POSIX shared memory compile-type choice is removed. Both shared
memory types are compiled-in and are selected at run time.
2) the shared memory type used by an experiment is recorded in the file
.SHM_TYPE.TXT. Currently implemented are "POSIXv2_SHM" (the new default for new
experiments), "POSIX_SHM", "MMAP_SHM" and "SYSV_SHM". (see system.c) (MMAP_SHM
is fully functional but is not recommended). The POSIXv2_SHM uses an improved
filename scheme (on Linux, see "ls -l /dev/shm") and permits multiple
experiments to coexist on a MacOS computer (where there is a severe limit on
shared memory filename length).
3) following a number of mishaps where "odbedit" has been run on the wrong
computer (causing havoc with ODB and .xxx.SHM files), for each experiment, the
hostname of the computer where the ODB shared memory is meant to reside is now
recorded in the file .SHM_HOST.TXT. Typically, this is the machine running
mserver, mhttpd and mlogger. If some client is accidentally started on the wrong
machine or if MIDAS_SERVER_HOST is accidentally left undefined, MIDAS will now
print a stern message reporting the hostname mismatch, tell the user to use the
mserver and refuse to run. The user has the choice of starting the client on the
correct computer (as reported in the error message), using the mserver (start
client with -H flag) or edit/delete the .SHM_HOST.TXT file (full pathname is
reported by the error message).

With this update, MIDAS on MacOS becomes fully functional (before, only one
experiment could be used at a time).

svn rev 5105
K.O.
  770   27 Jun 2011 Konstantin OlchanskiInfoupdated mhttpd history "export" function
The mhttpd history "export" function has been converted to the new midas history
interface and should now work for SQL-based history systems. In the process,
improvements by Eoin Butler (CERN AD-5/ALPHA) were merged - adding a UNIX
timestamp and a better text timestamp. Also now "export" outputs the actual
values from the history file - the scaling values from the definition of the
history plot panel are no longer applied.

Here is an example of the new file format:

Time, Timestamp, Run, Run State, SLOW
2011.06.21 15:45:21, 1308696321, 13292, 3, -89.1007

svn rev 5104
K.O.
  769   27 Jun 2011 Konstantin OlchanskiSuggestionBuild MIDAS debian packages using autoconf/automake.
> I deployed several Debian Linux boxes as the DAQ systems in our lab. But I
feel it's boring to build and install midas and its related softwares (such as
root) on each box.


Our solution at TRIUMF is to install such packages on a shared NFS filesystem
visible to all client computers. This works well for ROOT and but MIDAS we found
it nearly impossible to keep MIDAS versions in sync between different projects
and expiments, so each experiment uses it's own copy of MIDAS, usually located
in the experiment home directory ($HOME/packages/midas). Because we often need
to make local modifications to MIDAS sources (Makefile, etc), we do not
"install" MIDAS into non-user-writable /usr/local & etc.


> I use autoconf/automake


The promise (premise) of autoconf/automake is to "hide" system dependencies. The
scripts are supposed to automatically probe the build environment and construct
an appropriate Makefile.

In practice, the autotool scripts always have bugs and incorrect assumptions
about the build environment and only work well for a few standardized systems
(RHEL and Debian derivatives) where the differences are so trivial that
autotools is an overkill and a normal Makefile is adequate for the job.

In my experience, as soon as I try to build an autotool-ized package on anything
that does not look like RHEL or Debian, autotool scripts explode and have to be
debugged and kludged by hand. Anybody who has ever done that would agree with me
that one would rather hack the ugliest Makefile than any of the  autotool
generated gibberish.

And of course autotools have never handled cross-compilation in any reasonable
way. Since we do cross-compile MIDAS (for VxWorks and embedded Linux, see "make
crosscompile") a Makefile is required and it so happens that the same Makefile
also works for normal Linux and MacOS, thank you very much.



> Here are the installation:
> [*] executalbes -- /usr/lib/daq-midas/bin
> [*] library and objs -- /usr/lib/daq-midas/lib


Is this in violation of the LSB (or LFS)? I though they mandate that files
controlled by package manager should be /usr/bin/odbedit, /usr/lib64/libmidas.a,
etc (/usr/bin/midas/odbedit no permitted).


> gcc `mdaq-config --cflags` -c -o myfe.o myfe.c


Please check if your config scripts correctly handle the "-m32" and "-m64" flags
- we frequently cross-compile 32-bit MIDAS executables on 64-bit machines.


K.O.
  768   24 Jun 2011 Exaos LeeSuggestionBuild MIDAS debian packages using autoconf/automake.
Here is my story. I deployed several Debian Linux boxes as the DAQ systems in our lab. But I feel it's boring to build and install midas and its related softwares (such as root) on each box. So I need a local debian software repository and put midas and its related packages in it. First of all, I need a midas debian package. After a week's study and searching, I finally finished the job. Hope you feel it useful.

All the work is attached as "daq-midas_deb.tar.gz". The detail is followed. I also created several debian packages. But it's too large to be uploaded. I havn't my own site accessible from internet. So, if you need the debian packages, please give me an accessible ftp or other similar service, then I can upload them to you.

First, I use autoconf/automake to rewrite the building system of MIDAS. You can check it this way:
1. Untar daq-midas_deb.tar.gz somewhere, assumming ~/Temp.
2. cd ~/Temp/daq-midas
3. svn co -r 5065 svn+ssh://svn@savannah.psi.ch/repos/meg/midas/trunk midas
4. svn co -r 68 svn+ssh://svn@savannah.psi.ch/repos/meg/mxml/trunk mxml
5. cp -rvp debian/autoconf/* ./
6. ./configure --help
7. ./configure <--options>
8. make && make install

Then, I created the debian packages based on the new building files. You need to install root-system package from http://lcg-heppkg.web.cern.ch/lcg-heppkg/debian/. You can build debs this way:
1. untar daq-midas_deb.tar.gz somewhere, assuming ~/Temp.
2. cd ~/Temp/daq-midas
3. svn co -r 5065 svn+ssh://svn@savannah.psi.ch/repos/meg/midas/trunk midas
4. svn co -r 68 svn+ssh://svn@savannah.psi.ch/repos/meg/mxml/trunk mxml
5. dpkg-buildpackage -b -us -uc

I split the package into serverals parts:
  • daq-midas-doc -- The documents and references
  • daq-midas-root -- the midas runtime library and utilities built with root
  • daq-midas-noroot -- the midas runtime library and utilities built without root
  • daq-midas-dev-root -- the midas devel files (headers, objects, drivers, examples) built with root
  • daq-midas-dev-noroot -- the midas devel files (headers, objects, drivers, examples) built without root

Here are the installation:
  • executalbes -- /usr/lib/daq-midas/bin
  • library and objs -- /usr/lib/daq-midas/lib
  • headers -- /usr/lib/daq-midas/include
  • sources and drivers -- /usr/share/daq-midas/
  • docs and examples -- /usr/share/doc/daq-midas
  • mdaq-config -- /usr/bin/mdaq-config

I add an auto-generated shell script -- mdaq-config. It behaves just like "root-config". You can get midas build flags and link flags this way:
gcc `mdaq-config --cflags` -c -o myfe.o myfe.c
gcc `mdaq-config --libs` -o myfe myfe.o `mdaq-config --libdir`/mfe.o

Bugs and suggestions are welcomed.

P.S. Based on debian packages, I am planing to write another script, "mdaq.py":
  • each midas experiment will be configured in a file named "mdaq.yaml"
  • mdaq.py reads the configure file and prepare the daq environment, just like "examples/experiment/start_daq.sh"
  • mdaq.py will handle "start/stop/restart/info" about the daq codes.
The attached "mdaq.py" is the old one.
Attachment 1: daq-midas_deb.tar.gz
Attachment 2: mdaq.py
#!/usr/bin/env python
'''
   Python script to handle daq sessions using MIDAS/PSI.
   Auther: Exaos Lee <Exaos DOT Lee AT gmail DOT com>
   Date:   2009-07-15
'''

import os, os.path
import sys, signal, time
from commands     import getoutput
from ConfigParser import ConfigParser
from pprint       import pprint

class mdaq:
    _codes_ = { 'MSERVER':"MIDAS Server", 'MHTTPD':"MIDAS HTTPD Server",
                'ODBEDIT':"ODB Editor",   'LOGGER':"Data Logger",
                'PROG_FE':"Frontend",   'PROG_ANA':"Analyzer" }
    _env_ = dict()

    def __init__(self,**kws):
        env = dict()
        if kws.has_key('fname') and kws['fname'] != "":
            env = self.parse_conf(kws['fname'])
        self.apply_env(env)

    def parse_conf(self, fname):
        if not os.path.isfile(fname):
            print("**WARNING** File \"%s\" does not exist!"%fname)
            return None

        conf = ConfigParser()
        conf.read(fname)
        env={'CONF_FILE':fname }
        fcpath = os.path.dirname(fname)

        sec = 'EXP_INFO' ## Parsing Experiment Information
        env['EXP_INFO'] = [ self.safe_parse(conf,sec,'Name'),
                            self.safe_parse(conf,sec,'Info'), ]
        msg = self.safe_parse(conf,sec,'DAQ_DIR')
        if msg != "" and os.path.isdir(msg):
            dpath = msg
            if not os.path.isabs(msg):
                dpath = os.path.join(os.path.abspath(fcpath),msg)
            env['DAQ_DIR'] = os.path.normpath(dpath)

        ## Parsing MIDAS configuration
        env['MIDASSYS'] = ["MIDAS System Path",
                           self.safe_parse(conf,"MIDAS","MIDASSYS")]
        if env['MIDASSYS'][1]=="": env['MIDASSYS'][1] = self.get_default_msys()

        ## Parsing Info of programs
        for key in self._codes_.keys():
            code = self.parse_prog_opt(conf, key, fpath=fcpath)
            if code:
                env[key] = [self._codes_[key], ]
                env[key].extend(code)

        port = self.safe_parse(conf, "MHTTPD","PORT")
        if port != "":
            if not env.has_key('MHTTPD'):
                env['MHTTPD'] = ["MIDAS HTTP Server",
                                 os.path.join(env['MIDASSYS'][1],"bin/mhttpd"),
                                 "-h localhost -D"]
            if "-p %s"%port not in env['MHTTPD'][2]:
                env['MHTTPD'][2] = env['MHTTPD'][2] + " -p %s"%port

        return env

    def parse_prog_opt(self, cnf, sec, fpath="./"):
        name = self.safe_parse(cnf, sec, "NAME")
        path = self.safe_parse(cnf, sec, "PATH")
        fn = os.path.join(path,name)
        if name == "": fn = ""
        elif not os.path.isabs(fn):
            fn = os.path.normpath(os.path.join(os.path.abspath(fpath),fn))
        else:
            fn = os.path.normpath(fn)
        opts = self.safe_parse(cnf, sec, "Option")
        if opts != "" or name != "":
            return [fn, opts]

        return None
 
    def safe_parse(self, cnf, sec, opt):
        try:    return cnf.get(sec,opt)
        except: return ""

    def get_default_msys(self):
        if os.environ.has_key('MIDASSYS'): return os.environ['MIDASSYS']
        return "/opt/MIDAS.PSI/Version/Current"

    def apply_env(self, daq_env=dict()):
        env = daq_env
        if not env:
            print("** WARNING** No environment defined! Using the default values. ****")
            env = {'MIDASSYS':['MIDAS System Path', ""], 'CONF_FILE':"", }
        if not env.has_key('MIDASSYS'): env['MIDASSYS'] = ['MIDAS System Path',""]
        if env['MIDASSYS'][1]=="": env['MIDASSYS'][1] = self.get_default_msys()
        def_env = {
            'MSERVER' :["MIDAS Server",
                        os.path.join(env['MIDASSYS'][1],"bin/mserver"),
                        "-D", True],
            'MHTTPD'  :["MIDAS HTTP Server",
                        os.path.join(env['MIDASSYS'][1],"bin/mhttpd"),
                        "-h localhost -D -p 8080", True],
            'ODBEDIT' :["ODB Editor",
                        os.path.join(env['MIDASSYS'][1],"bin/odbedit"),
                        "-c clean", False],
            'LOGGER'  :["Data Logger",
                        os.path.join(env['MIDASSYS'][1],"bin/mlogger"),
                        "", True],
            'PROG_FE' :["Frontend","", "", True],
            'PROG_ANA':["Analyzer","", "", True],
            'EXP_INFO':["test","The test experiment"],
            'DAQ_DIR':os.path.join(os.environ['HOME'],"online/test") }

        for key in def_env.keys():
            if not env.has_key(key): env[key] = def_env[key]

        for key in self._codes_.keys():
            if env[key][1] == "": env[key][1] = def_env[key][1]
            if env[key][2] == "": env[key][2] = def_env[key][2]

        if not os.path.isdir(env['DAQ_DIR']):
            try: os.makedirs(env['DAQ_DIR'])
            except: print("ERROR to make file")

        ## Asign default program options
        exp_opt = "-e %s"%env['EXP_INFO'][0]
        for key in ['LOGGER', 'PROG_FE', 'PROG_ANA', "MHTTPD"]:
            if exp_opt not in env[key][2]:
                env[key][2] = exp_opt + ' ' + env[key][2]
            if "-D" not in env[key][2]:
                env[key][2] = env[key][2] + ' -D'
        if exp_opt not in env['ODBEDIT'][2]:
            env['ODBEDIT'][2] = env['ODBEDIT'][2] + ' ' + exp_opt

        self._env_ = env

    def print_conf(self):
        print "\n================= DAQ Config ====================="
        for key in self._env_.keys():
            print key,": ",
            pprint(self._env_[key])

    def info(self): self.print_conf()

    ## running programs
    def getpids(self, pname):
        return [int(k) for k in getoutput("pidof %s"%pname).strip().split()]

    def kill_prog(self,pname):
        for i in self.getpids(pname): os.kill(i,signal.SIGTERM)

    def run_prog(self, prog):
        if len(prog)>=4 and not prog[3]: return

        if len(prog)>=3 and prog[1]:
            print("Starting %s: %s"%(prog[0],prog[1]))
            os.system("%s %s"%(prog[1],prog[2]))
        else:
            print("%s: no executable exist!"%prog[0])

    def get_status(self,pfile):
        msg = "Not running!"
        pids = self.getpids( os.path.basename(pfile) )
        if pids: return 'PIDs = ' + str(pids)
        return msg

    def echo_status(self,pname,pfile):
        print("%s:\n   %s\n   "%(pname,pfile)
              + self.get_status(pfile))

    ## Session manage: start, stop, status, restart

    def status(self):
        print( "\n===== Session status for experiment \"%s\" =====\n" %
               self._env_['EXP_INFO'][0] )
        for code in ['MSERVER','MHTTPD','LOGGER','PROG_FE','PROG_ANA']:
            self.echo_status(self._env_[code][0], self._env_[code][1])

    def start(self):
        ## Running mserver & mhttpd
        ms_pids = self.getpids(os.path.basename(self._env_['MSERVER'][1]))
        if not ms_pids:
            self.run_prog(self._env_['MSERVER'])
            print("Killing %s ...\n"%self._env_['MHTTPD'][0])
            self.kill_prog(self._env_['MHTTPD'][1])
        if not self.getpids(os.path.basename(self._env_['MHTTPD'][1])):
            self.run_prog(self._env_['MHTTPD'])

        ## Running FE and Analyzer
        old_path = os.getcwd()
        os.chdir( self._env_['DAQ_DIR'] )

        # Init ODB
        print("Initializing ODB for experiment %s ..." % self._env_['EXP_INFO'][0])
        self.run_prog(self._env_['ODBEDIT'])
        time.sleep(1)

        # First stop, then start ...
        self.stop()
        time.sleep(1)

        # Start FE & ANA
        self.run_prog(self._env_['PROG_FE'])
        self.run_prog(self._env_['PROG_ANA'])
        time.sleep(1)

        # Start Logger
        self.run_prog(self._env_['LOGGER'])

        os.chdir(old_path)

    def stop(self):
        for key in ["LOGGER", "PROG_FE", "PROG_ANA"]:
            if self._env_[key][1]:
                print("Killing threads:\n  %s"%self._env_[key][1])
                self.kill_prog(self._env_[key][1])

    def stop_all(self):
        self.stop()
        for key in ['MHTTPD', 'MSERVER']:
            if self._env_[key][1]:
                print("Killing threads:\n  %s"%self._env_[key][1])
                self.kill_prog(self._env_[key][1])

    def restart(self): self.start()


if __name__=='__main__':
    from optparse import OptionParser

    usage = "usage: %prog [options] <command>"
    parser = OptionParser(usage=usage, version="%prog 0.1")
    parser.add_option("-c","--config", metavar="filename",
                      help="Read config from FILENAME")
    cmds = ["start","stop","stop_all","restart","status","info"]

    (opts,args) = parser.parse_args( sys.argv[1:] )
    if not args or len(args)>2:
         parser.print_help()
         print "\nCommands:\n\t",
         pprint(cmds)
         exit()

    fcnf = "daq.conf"
    if opts.config: fcnf = opts.config

    if args[0] in cmds:
        daq = mdaq(fname=fcnf)
        exec( "daq.%s()"%args[0] )
    else:
        parser.print_help()
        print "\nCommands:\n\t",
        pprint(cmds)
  767   21 Jun 2011 Stefan RittInfoNew MIDAS sequencer
A new sequencer for starting and stopping runs has been implemented. Although it is till kind of in a preliminary phase, it is usable, so I would like to share the syntax with you.

The sequencer runs inside mhttpd, and creates a new ODB subdirectory "/Sequencer". There is a new button on the status page called "Sequencer". In can run scripts in XML format, which reside on the server (where mhttpd is running). The sequencer is stateless, that means even if mhttpd is stopped and restarted, it resumes operation from where it has been stopped. Following statements are implemented:

  • <Comment>comment</Comment>
    a comment for this XML file, for information only

  • <ODBSet path="path">value</ODBSet>
    to set a value in the ODB

  • <ODBInc path="path">delta</ODBInc>
    to increment a value in the ODB

  • <RunDescription>Description</RunDescription>
    a run description which is stored under /Experiment/Run Parameters/Run Description.

  • <Transition>Start | Stop</Transition>
    to start or stop a run

  • <Loop n="n"> ... </Loop>
    to execute a loop n times. For infinite loops, "infinit" can be specified as n

  • <Wait for="events | ODBvalue | seconds" [path="ODB path"]>x</Wait>
    wait until a number of events is acquired (testing /Equipment/Trigger/Statistics/Events sent), or until a value in the ODB exceeds x, or wait for x seconds.

  • <Script [loop_counter="1"]>Script</Script>
    to call a script on the server side. Optionally, the loop counter(s) are passed to the script

Attached is a simple script which can be used as a starting point.
Attachment 1: seqtest.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<RunSequence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="">
<Comment>This is the XML test file</Comment>

<ODBSet path="/Experiment/Run Parameters/Comment">Test comment</ODBSet>
<RunDescription>Test Run</RunDescription>

<!-- do 10 runs -->
<Loop n="10">
   <!-- increment high voltage and wait for some time to settle -->
   <ODBInc path="/Equipment/HV/Variables/Demand[0]">10</ODBInc>
   <Wait for="seconds">10</Wait>

   <!-- start a run, acquire 3000 events -->
   <Transition>Start</Transition>
   <Wait for="events">3000</Wait>
   <Transition>Stop</Transition> -->
</Loop>
</RunSequence>
  766   20 Jun 2011 Stefan RittInfoJavascript ODB interface revised
The Javascript interface to the ODB has been revised. This extends the capabilities of custom web pages requesting data from the ODB. By grouping several request together, the number of round-trips is minimized and the response time is reduced. Following functions are new or extended:

  • ODBGet(path[, format]): This functions works now also with subdirectories in the ODB. The command ODBGet('/Runinfo') returns for example:
    1
    1
    1024
    0
    0
    0
    Mon Jun 20 09:40:14 2011
    1308588014
    Mon Jun 20 09:40:46 2011
    1308588046
    

  • ODBGetRecord(path), ODBExtractRecord(key): While ODBGet can be used for subdirectories, an easier way is to use ODBGetRecord and ODBExtractRecord. The first function retrieves the subtree (record), while the second one can be used to extract individual items. Here is an example:
    result = ODBGetRecord('/Runinfo');
    run_number = ODBExtractRecord(result, 'Run number');
    start_time = ODBExtractRecord(result, 'Start time');
    

  • ODBMGet(paths[, callback, formats]): This function ("Multi-Get") can be used to obtain ODB values from different paths in one call. The ODB paths have to be supplied in an array, the result is again an array. An optional callback routine might be supplied for asynchronous operation. Optional formats might be supplied if the resulting number should be formatted in a specific way. Here is an example:
       var req = new Array();
       req[0] = "/Runinfo/Run number";
       req[1] = "/Equipment/Trigger/Statistics/Events sent";
       var result = ODBMGet(req);
       run_number = result[0];
       events_sent = result[1];
    

The new functions are implemented in mhttpd revision 5075.
  765   20 Jun 2011 Jimmy NgaiForumCannot open input file (file too large?)
Dear All,

Thanks Konstantin Olchanski for providing me a hint. The file can be opened now after I 
changed the line: 

file->gzfile = gzopen(file_name, "rb");

in function ma_open() in mana.c to the followings: 

INT fd = open(file_name, O_RDONLY | O_LARGEFILE);
if (fd <= 0)
   return NULL;

file->gzfile = gzdopen(fd, "rb");

No modifications to the Makefile is needed in this case.

Best Regards,
Jimmy


> Dear All,
> 
> I got a "Cannot open input file" error when I tried to analyze a .mid.gz file with 
> size over 5 GB on a 32-bit Linux. The error traced back to gzopen() in mana.c 
> where it returned NULL when opening the file. I understand that 32-bit Linux may 
> not be able to handle files with size over 2 GB. I tried to add -
> D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 to CFLAGS in the Makefile of MIDAS and 
> the analyzer, but I still got the same error. Is there any workarounds that enable 
> me to analyze large files on 32-bit systems?
> 
> p.s. The data file was also produced on a 32-bit Linux.
> 
> Thanks & Best Regards,
> 
> Jimmy
  764   17 Jun 2011 Konstantin OlchanskiForumladd00.triumf.ca https ssl certificate update
The HTTPS SSL certificate on ladd00.triumf.ca has been updated. Same as the old
certificate, the new one is self-signed and your web browser may complain about
that and ask you to "save a security exception".

When you save the new certificate, you can verify that you are connected to the
real ladd00.triumf.ca by comparing the "SHA1 fingerprint" reported by your web
browser to the one given below (as reported by "svn update"):

Certificate information:
 - Hostname: ladd00.triumf.ca
 - Valid: from Jun 17 23:36:35 2011 GMT until Jun 16 23:36:35 2012 GMT
 - Issuer: DAQ, TRIUMF, Vancouver, BC, CA
 - Fingerprint: 2a:be:9f:9f:70:d4:dc:72:9f:63:bf:4f:fe:c0:2c:8f:a8:29:f2:f1

K.O.
  763   17 Jun 2011 Jimmy NgaiForumCannot open input file (file too large?)
Dear All,

I got a "Cannot open input file" error when I tried to analyze a .mid.gz file with 
size over 5 GB on a 32-bit Linux. The error traced back to gzopen() in mana.c 
where it returned NULL when opening the file. I understand that 32-bit Linux may 
not be able to handle files with size over 2 GB. I tried to add -
D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 to CFLAGS in the Makefile of MIDAS and 
the analyzer, but I still got the same error. Is there any workarounds that enable 
me to analyze large files on 32-bit systems?

p.s. The data file was also produced on a 32-bit Linux.

Thanks & Best Regards,

Jimmy
  762   24 May 2011 Jianglai LiuForumsimple example frontend for V1720
Thanks all for the kind help. This did point me to the right direction. I was now able to make v1720.c as well as my MIDAS frontend (thanks to
Jimmy's example) talking to V1720, and read out the waveform bank.

However the readout values did not seem quite right. I fed in a PMT-like pulse of about 0.1 V and 50 ns wide, with an external trigger just in time.
However, the readout by both v1720.c stand-alone code, and my midas frontend seemed to be flat noise.

I tried to play with the post trigger value, as well as the DAC setting of V1720. None seemed to help.

BTW I tested my V1720 board functionality by using the CAEN windows software (CAENScope and WaveDump). They worked just fine.

Any suggestions? Attached is my modified v1720.c code.


Pierre-Andre Amaudruz wrote:

Jianglai Liu wrote:
Hi,

Who has a good example of a frontend program using CAEN V1718 VME-USB bridge and
V1720 FADC? I am trying to set up the DAQ for such a simple system.

I put together a frontend which talks to the VME. However it gets stuck at
"Calibrating" in initialize_equipment().

I'd appreciate some help!

Thanks,
Jianglai


Under the drivers/vme you can find code for the v1720.c (VME access) and ov1720.c
(A2818/A3818 PCIe optical link access). For testing the hardware, we use this code compiled and linked
with MAIN_ENABLE to confirm its functionality. You may want to do the same for your USB. Once this
is under control, the Midas frontend implementation using the same driver shouldn't give you trouble.
Attachment 1: v1720.c
/*********************************************************************

  Name:         v1720.c
  Created by:   Pierre-A. Amaudruz / K.Olchanski

  Contents:     V1720 8 ch. 12bit 250Msps
 
  $Id: v1720.c 4728 2010-05-12 05:34:44Z svn $
*********************************************************************/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
//#include "midas.h"
#include "v1720drv.h"
#include "mvmestd.h"


// Buffer organization map for number of samples
uint32_t V1720_NSAMPLES_MODE[11] = { (1<<20), (1<<19), (1<<18), (1<<17), (1<<16), (1<<15)
			       ,(1<<14), (1<<13), (1<<12), (1<<11), (1<<10)};

/*****************************************************************/
/*
Read V1720 register value
*/
static uint32_t regRead(MVME_INTERFACE *mvme, uint32_t base, int offset)
{
  mvme_set_am(mvme, MVME_AM_A32);
  mvme_set_dmode(mvme, MVME_DMODE_D32);
  return mvme_read_value(mvme, base + offset);
}

/*****************************************************************/
/*
Write V1720 register value
*/
static void regWrite(MVME_INTERFACE *mvme, uint32_t base, int offset, uint32_t value)
{
  mvme_set_am(mvme, MVME_AM_A32);
  mvme_set_dmode(mvme, MVME_DMODE_D32);
  mvme_write_value(mvme, base + offset, value);
}

/*****************************************************************/
uint32_t v1720_RegisterRead(MVME_INTERFACE *mvme, uint32_t base, int offset)
{
  return regRead(mvme, base, offset);
}

/*****************************************************************/
void v1720_RegisterWrite(MVME_INTERFACE *mvme, uint32_t base, int offset, uint32_t value)
{
  regWrite(mvme, base, offset, value);
}

/*****************************************************************/
void v1720_Reset(MVME_INTERFACE *mvme, uint32_t base)
{
  regWrite(mvme, base, V1720_SW_RESET, 0);
}

/*****************************************************************/
void v1720_TrgCtl(MVME_INTERFACE *mvme, uint32_t base, uint32_t reg, uint32_t mask)
{
  regWrite(mvme, base, reg, mask);
}

/*****************************************************************/
void v1720_ChannelCtl(MVME_INTERFACE *mvme, uint32_t base, uint32_t reg, uint32_t mask)
{
  regWrite(mvme, base, reg, mask);
}

/*****************************************************************/
void v1720_ChannelSet(MVME_INTERFACE *mvme, uint32_t base, uint32_t channel, uint32_t what, uint32_t that)
{
  uint32_t reg, mask;

  if (what == V1720_CHANNEL_THRESHOLD)   mask = 0x0FFF;
  if (what == V1720_CHANNEL_OUTHRESHOLD) mask = 0x0FFF;
  if (what == V1720_CHANNEL_DAC)         mask = 0xFFFF;
  reg = what | (channel << 8);
  printf("base:0x%x reg:0x%x, this:%x\n", base, reg, that);
  regWrite(mvme, base, reg, (that & 0xFFF));
}

/*****************************************************************/
uint32_t v1720_ChannelGet(MVME_INTERFACE *mvme, uint32_t base, uint32_t channel, uint32_t what)
{
  uint32_t reg, mask;

  if (what == V1720_CHANNEL_THRESHOLD)   mask = 0x0FFF;
  if (what == V1720_CHANNEL_OUTHRESHOLD) mask = 0x0FFF;
  if (what == V1720_CHANNEL_DAC)         mask = 0xFFFF;
  reg = what | (channel << 8);
  return regRead(mvme, base, reg);
}

/*****************************************************************/
void v1720_ChannelThresholdSet(MVME_INTERFACE *mvme, uint32_t base, uint32_t channel, uint32_t threshold)
{
  uint32_t reg;
  reg = V1720_CHANNEL_THRESHOLD | (channel << 8);
  printf("base:0x%x reg:0x%x, threshold:%x\n", base, reg, threshold);
  regWrite(mvme, base, reg, (threshold & 0xFFF));
}

/*****************************************************************/
void v1720_ChannelOUThresholdSet(MVME_INTERFACE *mvme, uint32_t base, uint32_t channel, uint32_t threshold)
{
  uint32_t reg;
  reg = V1720_CHANNEL_OUTHRESHOLD | (channel << 8);
  printf("base:0x%x reg:0x%x, outhreshold:%x\n", base, reg, threshold);
  regWrite(mvme, base, reg, (threshold & 0xFFF));
}

/*****************************************************************/
void v1720_ChannelDACSet(MVME_INTERFACE *mvme, uint32_t base, uint32_t channel, uint32_t dac)
{
  uint32_t reg;

  reg = V1720_CHANNEL_DAC | (channel << 8);
  printf("base:0x%x reg:0x%x, DAC:%x\n", base, reg, dac);
  regWrite(mvme, base, reg, (dac & 0xFFFF));
}

/*****************************************************************/
int v1720_ChannelDACGet(MVME_INTERFACE *mvme, uint32_t base, uint32_t channel, uint32_t *dac)
{
  uint32_t reg;
  int   status;

  reg = V1720_CHANNEL_DAC | (channel << 8);
  *dac = regRead(mvme, base, reg);
  reg = V1720_CHANNEL_STATUS | (channel << 8);
  status = regRead(mvme, base, reg);
  return status;
}

/*****************************************************************/
void v1720_Align64Set(MVME_INTERFACE *mvme, uint32_t base)
{
  regWrite(mvme, base, V1720_VME_CONTROL, V1720_ALIGN64);
}

/*****************************************************************/
void v1720_AcqCtl(MVME_INTERFACE *mvme, uint32_t base, uint32_t operation)
{
  uint32_t reg;
  
  reg = regRead(mvme, base, V1720_ACQUISITION_CONTROL);  
  switch (operation) {
  case V1720_RUN_START:
    regWrite(mvme, base, V1720_ACQUISITION_CONTROL, (reg | 0x4));
    break;
  case V1720_RUN_STOP:
    regWrite(mvme, base, V1720_ACQUISITION_CONTROL, (reg & ~(0x4)));
    break;
  case V1720_REGISTER_RUN_MODE:
    regWrite(mvme, base, V1720_ACQUISITION_CONTROL, (reg & ~(0x3)));
    break;
  case V1720_SIN_RUN_MODE:
    regWrite(mvme, base, V1720_ACQUISITION_CONTROL, (reg | 0x01));
    break;
  case V1720_SIN_GATE_RUN_MODE:
    regWrite(mvme, base, V1720_ACQUISITION_CONTROL, (reg | 0x02));
    break;
  case V1720_MULTI_BOARD_SYNC_MODE:
    regWrite(mvme, base, V1720_ACQUISITION_CONTROL, (reg | 0x03));
    break;
  case V1720_COUNT_ACCEPTED_TRIGGER:
    regWrite(mvme, base, V1720_ACQUISITION_CONTROL, (reg | 0x08));
    break;
  case V1720_COUNT_ALL_TRIGGER:
    regWrite(mvme, base, V1720_ACQUISITION_CONTROL, (reg & ~(0x08)));
    break;
  default:
    break;
  }
}

/*****************************************************************/
void v1720_info(MVME_INTERFACE *mvme, uint32_t base, int *nchannels, uint32_t *n32word)
{
  int i, chanmask;

  // Evaluate the event size
  // Number of samples per channels
  *n32word = V1720_NSAMPLES_MODE[regRead(mvme, base, V1720_BUFFER_ORGANIZATION)];

  // times the number of active channels
  chanmask = 0xff & regRead(mvme, base, V1720_CHANNEL_EN_MASK); 
  *nchannels = 0;
  for (i=0;i<8;i++) {
    if (chanmask & (1<<i))
      *nchannels += 1;
  }

  *n32word *= *nchannels;
  *n32word /= 2;   // 2 samples per 32bit word
  *n32word += 4;   // Headers
}

/*****************************************************************/
uint32_t v1720_BufferOccupancy(MVME_INTERFACE *mvme, uint32_t base, uint32_t channel)
{
  uint32_t reg;
  reg = V1720_BUFFER_OCCUPANCY + (channel<<16);
  return regRead(mvme, base, reg);
}


/*****************************************************************/
uint32_t v1720_BufferFree(MVME_INTERFACE *mvme, uint32_t base, int nbuffer)
{
  int mode;

  mode = regRead(mvme, base, V1720_BUFFER_ORGANIZATION);
  if (nbuffer <= (1<< mode) ) {
    regWrite(mvme, base, V1720_BUFFER_FREE, nbuffer);
    return mode;
  } else
    return mode;
}

/*****************************************************************/
uint32_t v1720_BufferFreeRead(MVME_INTERFACE *mvme, uint32_t base)
{
  return regRead(mvme, base, V1720_BUFFER_FREE);
}

/*****************************************************************/
uint32_t v1720_DataRead(MVME_INTERFACE *mvme, uint32_t base, uint32_t *pdata, uint32_t n32w)
{
  uint32_t i;

  for (i=0;i<n32w;i++) {
    *pdata = regRead(mvme, base, V1720_EVENT_READOUT_BUFFER);
    if (*pdata != 0xffffffff)
      pdata++;
    else
      break;
  }
  return i;
}

/********************************************************************/
/** v1720_DataBlockRead
Read N entries (32bit) 
@param mvme vme structure
@param base  base address
@param pdest Destination pointer
@return nentry
*/
uint32_t v1720_DataBlockRead(MVME_INTERFACE *mvme, uint32_t base, uint32_t *pdest, uint32_t *nentry)
{
  int status;

  mvme_set_am(  mvme, MVME_AM_A32);
  mvme_set_dmode(  mvme, MVME_DMODE_D32);
  //mvme_set_blt(  mvme, MVME_BLT_MBLT64);
  //mvme_set_blt(  mvme, MVME_BLT_NONE);
  mvme_set_blt(mvme, MVME_BLT_BLT32);
  //mvme_set_blt(  mvme, 0);

  // Transfer in MBLT64 (8bytes), nentry is in 32bits(VF48)
  // *nentry * 8 / 2
  status = mvme_read(mvme, pdest, base+V1720_EVENT_READOUT_BUFFER, 4);
  //printf("status = %d\n",status);
  if (status != MVME_SUCCESS)
    return 0;

  return (*nentry);
}


/*****************************************************************/
void  v1720_Status(MVME_INTERFACE *mvme, uint32_t base)
{
  printf("================================================\n");
  printf("V1720 at A32 0x%x\n", (int)base);
  printf("Board ID             : 0x%x\n", regRead(mvme, base, V1720_BOARD_ID));
  printf("Board Info           : 0x%x\n", regRead(mvme, base, V1720_BOARD_INFO));
  printf("Acquisition status   : 0x%8.8x\n", regRead(mvme, base, V1720_ACQUISITION_STATUS));
  printf("================================================\n");
}

/*****************************************************************/
/**
Sets all the necessary paramters for a given configuration.
The configuration is provided by the mode argument.
Add your own configuration in the case statement. Let me know
your setting if you want to include it in the distribution.
- <b>Mode 1</b> : 

@param *mvme VME structure
@param  base Module base address
@param mode  Configuration mode number
@return 0: OK. -1: Bad
*/
... 169 more lines ...
  761   18 May 2011 Jimmy NgaiForumsimple example frontend for V1720

Jianglai Liu wrote:
Hi,

Who has a good example of a frontend program using CAEN V1718 VME-USB bridge and
V1720 FADC? I am trying to set up the DAQ for such a simple system.

I put together a frontend which talks to the VME. However it gets stuck at
"Calibrating" in initialize_equipment().

I'd appreciate some help!

Thanks,
Jianglai


Hi Jianglai,

I don't have an exmaple of using V1718 with V1720, but I have been using V1718 with V792N for a long time.

You may find in the attachment an example frontend program and my drivers for V1718 and V792N written in MVMESTD format. They have to be linked with the CAENVMELib library and other essential MIDAS stuffs.

Regards,
Jimmy
Attachment 1: frontend.c
/********************************************************************\

  Name:         frontend.c
  Created by:   Jimmy Ngai

  Date:         May 9, 2010

  Contents:     Experiment specific readout code (user part) of
                Midas frontend.
		Supported VME modules:
		CAEN V1718 VME-USB Bridge
		CAEN V792N 16 CH QDC

  $Id: $

\********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include "midas.h"
#include "mcstd.h"
#include "mvmestd.h"
#include "experim.h"
#include "vme/v792n.h"

/* make frontend functions callable from the C framework */
#ifdef __cplusplus
extern "C" {
#endif

/*-- Globals -------------------------------------------------------*/

/* The frontend name (client name) as seen by other MIDAS clients   */
char *frontend_name = "Frontend";
/* The frontend file name, don't change it */
char *frontend_file_name = __FILE__;

/* frontend_loop is called periodically if this variable is TRUE    */
BOOL frontend_call_loop = FALSE;

/* a frontend status page is displayed with this frequency in ms */
INT display_period = 3000;

/* maximum event size produced by this frontend */
INT max_event_size = 10000;

/* maximum event size for fragmented events (EQ_FRAGMENTED) */
INT max_event_size_frag = 5 * 1024 * 1024;

/* buffer size to hold events */
INT event_buffer_size = 10 * 10000;

/* number of channels */
#define N_ADC      16

/* VME hardware */
MVME_INTERFACE *myvme;

/* VME base address */
DWORD V1718_BASE  = 0x12000000;
DWORD V792N_BASE  = 0x32100000;

/*-- Function declarations -----------------------------------------*/

INT frontend_init();
INT frontend_exit();
INT begin_of_run(INT run_number, char *error);
INT end_of_run(INT run_number, char *error);
INT pause_run(INT run_number, char *error);
INT resume_run(INT run_number, char *error);
INT frontend_loop();

INT read_trigger_event(char *pevent, INT off);

/*-- Equipment list ------------------------------------------------*/

#undef USE_INT

EQUIPMENT equipment[] = {

   {"Trigger",               /* equipment name */
    {1, 0,                   /* event ID, trigger mask */
     "SYSTEM",               /* event buffer */
#ifdef USE_INT
     EQ_INTERRUPT,           /* equipment type */
#else
     EQ_POLLED,              /* equipment type */
#endif
     LAM_SOURCE(CRATE, LAM_STATION(SLOT_ADC)), /* event source */
     "MIDAS",                /* format */
     TRUE,                   /* enabled */
     RO_RUNNING |            /* read only when running */
     RO_ODB,                 /* and update ODB */
     500,                    /* poll for 500ms */
     0,                      /* stop run after this event limit */
     0,                      /* number of sub events */
     0,                      /* don't log history */
     "", "", "",},
    read_trigger_event,      /* readout routine */
    },

   {""}
};

#ifdef __cplusplus
}
#endif

/********************************************************************\
              Callback routines for system transitions

  These routines are called whenever a system transition like start/
  stop of a run occurs. The routines are called on the following
  occations:

  frontend_init:  When the frontend program is started. This routine
                  should initialize the hardware.

  frontend_exit:  When the frontend program is shut down. Can be used
                  to releas any locked resources like memory, commu-
                  nications ports etc.

  begin_of_run:   When a new run is started. Clear scalers, open
                  rungates, etc.

  end_of_run:     Called on a request to stop a run. Can send
                  end-of-run event and close run gates.

  pause_run:      When a run is paused. Should disable trigger events.

  resume_run:     When a run is resumed. Should enable trigger events.

\********************************************************************/

INT init_vme_modules()
{
   /* default settings */

   v792n_SoftReset(myvme, V792N_BASE);
   v792n_Setup(myvme, V792N_BASE, 2);
//   v792n_Status(myvme, V792N_BASE);

   return SUCCESS;
}

/*-- Frontend Init -------------------------------------------------*/

INT frontend_init()
{
   INT status;

   /* open VME interface */
   status = mvme_open(&myvme, 0);

   /* set am to A32 non-privileged Data */
   mvme_set_am(myvme, MVME_AM_A32_ND);

   /* initialize all VME modules */
   init_vme_modules();

   v792n_OfflineSet(myvme, V792N_BASE);
   v792n_DataClear(myvme, V792N_BASE);

   /* print message and return FE_ERR_HW if frontend should not be started */
   if (status != MVME_SUCCESS) {
      cm_msg(MERROR, "frontend_init", "VME interface could not be opened.");
      return FE_ERR_HW;
   }

   return SUCCESS;
}

/*-- Frontend Exit -------------------------------------------------*/

INT frontend_exit()
{
   /* close VME interface */
   mvme_close(myvme);

   return SUCCESS;
}

/*-- Begin of Run --------------------------------------------------*/

INT begin_of_run(INT run_number, char *error)
{
   /* Initialize all VME modules */
//   init_vme_modules();

   v792n_DataClear(myvme, V792N_BASE);
   v792n_OnlineSet(myvme, V792N_BASE);

   return SUCCESS;
}

/*-- End of Run ----------------------------------------------------*/

INT end_of_run(INT run_number, char *error)
{
   v792n_OfflineSet(myvme, V792N_BASE);
   v792n_DataClear(myvme, V792N_BASE);

   return SUCCESS;
}

/*-- Pause Run -----------------------------------------------------*/

INT pause_run(INT run_number, char *error)
{
   v792n_OfflineSet(myvme, V792N_BASE);

   return SUCCESS;
}

/*-- Resuem Run ----------------------------------------------------*/

INT resume_run(INT run_number, char *error)
{
   v792n_OnlineSet(myvme, V792N_BASE);

   return SUCCESS;
}

/*-- Frontend Loop -------------------------------------------------*/

INT frontend_loop()
{
   /* if frontend_call_loop is true, this routine gets called when
      the frontend is idle or once between every event */

   return SUCCESS;
}

/*------------------------------------------------------------------*/

/********************************************************************\

  Readout routines for different events

\********************************************************************/

/*-- Trigger event routines ----------------------------------------*/

INT poll_event(INT source, INT count, BOOL test)
/* Polling routine for events. Returns TRUE if event
   is available. If test equals TRUE, don't return. The test
   flag is used to time the polling */
{
   INT i;
   DWORD lam = 0;

   for (i = 0; i < count; i++) {
      lam = v792n_DataReady(myvme, V792N_BASE);

      if (lam)
         if (!test)
            return lam;
   }

   return 0;
}

/*-- Interrupt configuration ---------------------------------------*/

INT interrupt_configure(INT cmd, INT source, POINTER_T adr)
{
   switch (cmd) {
   case CMD_INTERRUPT_ENABLE:
      break;
   case CMD_INTERRUPT_DISABLE:
      break;
   case CMD_INTERRUPT_ATTACH:
      break;
   case CMD_INTERRUPT_DETACH:
      break;
   }
   return SUCCESS;
}

/*-- Event readout -------------------------------------------------*/

INT read_v792n(INT base, const char *bk_name, char *pevent, INT n_chn)
{
   INT i;
   INT nentry = 0, counter;
   DWORD data[V792N_MAX_CHANNELS+2];
   WORD *pdata;

   /* event counter */
//   v792n_EvtCntRead(myvme, base, &counter);

   /* read event */
   v792n_EventRead(myvme, base, data, &nentry);

   /* clear ADC */
//   v792n_DataClear(myvme, base);

   /* create ADC bank */
   bk_create(pevent, bk_name, TID_WORD, &pdata);

... 29 more lines ...
Attachment 2: v1718.h
/*********************************************************************

  Name:         v1718.h
  Created by:   Jimmy Ngai

  Contents:     V1718 VME-USB2.0 bridge include

  $Id: $
*********************************************************************/
#ifndef  V1718_INCLUDE_H
#define  V1718_INCLUDE_H

#include <stdio.h>
#include <string.h>
#include "mvmestd.h"

#ifdef __cplusplus
extern "C" {
#endif

#define  V1718_STATUS_RO          (DWORD) (0x0000)
#define  V1718_VME_CTRL_RW        (DWORD) (0x0001)
#define  V1718_FW_REV_RO          (DWORD) (0x0002)
#define  V1718_FW_DWNLD_RW        (DWORD) (0x0003)
#define  V1718_FL_ENA_RW          (DWORD) (0x0004)
#define  V1718_IRQ_STAT_RO        (DWORD) (0x0005)
#define  V1718_IN_REG_RW          (DWORD) (0x0008)
#define  V1718_OUT_REG_S_RW       (DWORD) (0x000A)
#define  V1718_IN_MUX_S_RW        (DWORD) (0x000B)
#define  V1718_OUT_MUX_S_RW       (DWORD) (0x000C)
#define  V1718_LED_POL_S_RW       (DWORD) (0x000D)
#define  V1718_OUT_REG_C_WO       (DWORD) (0x0010)
#define  V1718_IN_MUX_C_WO        (DWORD) (0x0011)
#define  V1718_OUT_MAX_C_WO       (DWORD) (0x0012)
#define  V1718_LED_POL_C_WO       (DWORD) (0x0013)
#define  V1718_PULSEA_0_RW        (DWORD) (0x0016)
#define  V1718_PULSEA_1_RW        (DWORD) (0x0017)
#define  V1718_PULSEB_0_RW        (DWORD) (0x0019)
#define  V1718_PULSEB_1_RW        (DWORD) (0x001A)
#define  V1718_SCALER0_RW         (DWORD) (0x001C)
#define  V1718_SCALER1_RO         (DWORD) (0x001D)
#define  V1718_DISP_ADL_RO        (DWORD) (0x0020)
#define  V1718_DISP_ADH_RO        (DWORD) (0x0021)
#define  V1718_DISP_DTL_RO        (DWORD) (0x0022)
#define  V1718_DISP_DTH_RO        (DWORD) (0x0023)
#define  V1718_DISP_PC1_RO        (DWORD) (0x0024)
#define  V1718_DISP_PC2_RO        (DWORD) (0x0025)
#define  V1718_LM_ADL_RW          (DWORD) (0x0028)
#define  V1718_LM_ADH_RW          (DWORD) (0x0029)
#define  V1718_LM_C_RW            (DWORD) (0x002C)

WORD v1718_Read16(MVME_INTERFACE *mvme, DWORD base, int offset);
void v1718_Write16(MVME_INTERFACE *mvme, DWORD base, int offset, WORD value);
DWORD v1718_Read32(MVME_INTERFACE *mvme, DWORD base, int offset);
void v1718_Write32(MVME_INTERFACE *mvme, DWORD base, int offset, DWORD value);

void v1718_MultiRead(MVME_INTERFACE *mvme, DWORD *addrs, DWORD *value, int ncycle, int *am, int *dmode);
void v1718_MultiWrite(MVME_INTERFACE *mvme, DWORD *addrs, DWORD *value, int ncycle, int *am, int *dmode);
void v1718_MultiRead16(MVME_INTERFACE *mvme, DWORD *addrs, WORD *value, int ncycle);
void v1718_MultiWrite16(MVME_INTERFACE *mvme, DWORD *addrs, WORD *value, int ncycle);
void v1718_MultiRead32(MVME_INTERFACE *mvme, DWORD *addrs, DWORD *value, int ncycle);
void v1718_MultiWrite32(MVME_INTERFACE *mvme, DWORD *addrs, DWORD *value, int ncycle);

void v1718_PulserConfSet(MVME_INTERFACE *mvme, WORD pulser, DWORD period, DWORD width, WORD pulseNo);
void v1718_PulserStart(MVME_INTERFACE *mvme, WORD pulser);
void v1718_PulserStop(MVME_INTERFACE *mvme, WORD pulser);

  enum v1718_PulserSelect {
    v1718_pulserA=0x0,
    v1718_pulserB=0x1,
  };

#ifdef __cplusplus
}
#endif

#endif // V1718_INCLUDE_H

/* emacs
 * Local Variables:
 * mode:C
 * mode:font-lock
 * tab-width: 8
 * c-basic-offset: 2
 * End:
 */
Attachment 3: v1718.c
/********************************************************************

  Name:         v1718.c
  Created by:   Jimmy Ngai

  Contents:     Midas VME standard (MVMESTD) layer for CAEN V1718
                VME-USB2.0 Bridge using CAENVMElib Linux library

  $Id: $

\********************************************************************/

#ifdef __linux__
#ifndef OS_LINUX
#define OS_LINUX
#endif
#endif

#ifdef OS_LINUX

#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "CAENVMElib.h"

#endif // OS_LINUX

#include "v1718.h"

/*------------------------------------------------------------------*/

/********************************************************************\

  MIDAS VME standard (MVMESTD) functions

\********************************************************************/

int mvme_open(MVME_INTERFACE **vme, int idx)
{
   *vme = (MVME_INTERFACE *) malloc(sizeof(MVME_INTERFACE));
   if (*vme == NULL)
      return MVME_NO_MEM;

   memset(*vme, 0, sizeof(MVME_INTERFACE));

   /* open VME */
   if (CAENVME_Init(cvV1718, 0, idx, &(*vme)->handle) != cvSuccess)
      return MVME_NO_INTERFACE;

   /* default values */
   (*vme)->am        = MVME_AM_DEFAULT;
   (*vme)->dmode     = MVME_DMODE_D32;
   (*vme)->blt_mode  = MVME_BLT_NONE;
   (*vme)->table     = NULL; // not used

   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_close(MVME_INTERFACE *vme)
{
   CAENVME_End(vme->handle);

   free(vme);

   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_sysreset(MVME_INTERFACE *vme)
{
   CAENVME_SystemReset(vme->handle);

   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_write(MVME_INTERFACE *vme, mvme_addr_t vme_addr, void *src, mvme_size_t n_bytes)
{
   mvme_size_t i;
   int status=0, n;
   int hvme;
   hvme = vme->handle;

   n = 0;

   /* D8 */
   if (vme->dmode == MVME_DMODE_D8) {
      for (i=0 ; i<n_bytes ; i++)
         status = CAENVME_WriteCycle(hvme, vme_addr, src+i, vme->am, cvD8);
      n = n_bytes;
   /* D16 */
   } else if (vme->dmode == MVME_DMODE_D16) {
      /* normal I/O */
      if (vme->blt_mode == MVME_BLT_NONE) {
         for (i=0 ; i<(n_bytes>>1) ; i++)
            status = CAENVME_WriteCycle(hvme, vme_addr, src+(i<<1), vme->am, cvD16);
         n = n_bytes;
      /* FIFO BLT */
      } else if ((vme->blt_mode == MVME_BLT_BLT32FIFO) || (vme->blt_mode == MVME_BLT_MBLT64FIFO))
         status = CAENVME_FIFOBLTWriteCycle(hvme, vme_addr, src, n_bytes, vme->am, cvD16, &n);
      /* BLT */
      else
         status = CAENVME_BLTWriteCycle(hvme, vme_addr, src, n_bytes, vme->am, cvD16, &n);
   /* D32 */
   } else if (vme->dmode == MVME_DMODE_D32) {
      /* normal I/O */
      if (vme->blt_mode == MVME_BLT_NONE) {
         for (i=0 ; i<(n_bytes>>2) ; i++)
            status = CAENVME_WriteCycle(hvme, vme_addr, src+(i<<2), vme->am, cvD32);
         n = n_bytes;
      /* FIFO BLT */
      } else if (vme->blt_mode == MVME_BLT_BLT32FIFO)
         status = CAENVME_FIFOBLTWriteCycle(hvme, vme_addr, src, n_bytes, vme->am, cvD32, &n);
      /* BLT */
      else
         status = CAENVME_BLTWriteCycle(hvme, vme_addr, src, n_bytes, vme->am, cvD32, &n);
   /* D64 */
   } else if (vme->dmode == MVME_DMODE_D64) {
      /* FIFO MBLT */
      if (vme->blt_mode == MVME_BLT_MBLT64FIFO) 
         status = CAENVME_FIFOMBLTWriteCycle(hvme, vme_addr, src, n_bytes, vme->am, &n);
      /* MBLT */
      else
         status = CAENVME_MBLTWriteCycle(hvme, vme_addr, src, n_bytes, vme->am, &n);
   }

   if (status != cvSuccess)
      n = 0;

   return n;
}

/*------------------------------------------------------------------*/

int mvme_write_value(MVME_INTERFACE *vme, mvme_addr_t vme_addr, unsigned int value)
{
   int status=0, n;
   int hvme;
   hvme = vme->handle;

   if (vme->dmode == MVME_DMODE_D8)
      n = 1;
   else if (vme->dmode == MVME_DMODE_D16)
      n = 2;
   else
      n = 4;

   /* D8 */
   if (vme->dmode == MVME_DMODE_D8)
      status = CAENVME_WriteCycle(hvme, vme_addr, &value, vme->am, cvD8);
   /* D16 */
   else if (vme->dmode == MVME_DMODE_D16)
      status = CAENVME_WriteCycle(hvme, vme_addr, &value, vme->am, cvD16);
   /* D32 */
   else if (vme->dmode == MVME_DMODE_D32)
      status = CAENVME_WriteCycle(hvme, vme_addr, &value, vme->am, cvD32);

   if (status != cvSuccess)
      n = 0;

   return n;
}

/*------------------------------------------------------------------*/

int mvme_read(MVME_INTERFACE *vme, void *dst, mvme_addr_t vme_addr, mvme_size_t n_bytes)
{
   mvme_size_t i;
   int status=0, n;
   int hvme;
   hvme = vme->handle;

   n = 0;

   /* D8 */
   if ((vme->dmode == MVME_DMODE_D8) || (vme->blt_mode == MVME_BLT_NONE)) {
      for (i=0 ; i<n_bytes ; i++)
         status = CAENVME_ReadCycle(hvme, vme_addr, dst+i, vme->am, cvD8);
      n = n_bytes;
   /* D16 */
   } else if (vme->dmode == MVME_DMODE_D16) {
      /* normal I/O */
      if (vme->blt_mode == MVME_BLT_NONE) {
         for (i=0 ; i<(n_bytes>>1) ; i++)
            status = CAENVME_ReadCycle(hvme, vme_addr, dst+(i<<1), vme->am, cvD16);
         n = n_bytes;
      /* FIFO BLT */
      } else if ((vme->blt_mode == MVME_BLT_BLT32FIFO) || (vme->blt_mode == MVME_BLT_MBLT64FIFO))
         status = CAENVME_FIFOBLTReadCycle(hvme, vme_addr, dst, n_bytes, vme->am, cvD16, &n);
      /* BLT */
      else
         status = CAENVME_BLTReadCycle(hvme, vme_addr, dst, n_bytes, vme->am, cvD16, &n);
   /* D32 */
   } else if (vme->dmode == MVME_DMODE_D32) {
      /* normal I/O */
      if (vme->blt_mode == MVME_BLT_NONE) {
         for (i=0 ; i<(n_bytes>>2) ; i++)
            status = CAENVME_ReadCycle(hvme, vme_addr, dst+(i<<2), vme->am, cvD32);
         n = n_bytes;
      /* FIFO BLT */
      } else if (vme->blt_mode == MVME_BLT_BLT32FIFO)
         status = CAENVME_FIFOBLTReadCycle(hvme, vme_addr, dst, n_bytes, vme->am, cvD32, &n);
      /* BLT */
      else
         status = CAENVME_BLTReadCycle(hvme, vme_addr, dst, n_bytes, vme->am, cvD32, &n);
   /* D64 */
   } else if (vme->dmode == MVME_DMODE_D64) {
      /* FIFO MBLT */
      if (vme->blt_mode == MVME_BLT_MBLT64FIFO)
         status = CAENVME_FIFOMBLTReadCycle(hvme, vme_addr, dst, n_bytes, vme->am, &n);
      /* MBLT */
      else
         status = CAENVME_MBLTReadCycle(hvme, vme_addr, dst, n_bytes, vme->am, &n);
   }

   if ((status != cvSuccess) && (status != cvBusError))
      n = 0;

   return n;
}

/*------------------------------------------------------------------*/

unsigned int mvme_read_value(MVME_INTERFACE *vme, mvme_addr_t vme_addr)
{
   unsigned int data;
   int status=0;
   int hvme;
   hvme = vme->handle;

   data = 0;

   /* D8 */
   if (vme->dmode == MVME_DMODE_D8)
      status = CAENVME_ReadCycle(hvme, vme_addr, &data, vme->am, cvD8);
   /* D16 */
   else if (vme->dmode == MVME_DMODE_D16)
      status = CAENVME_ReadCycle(hvme, vme_addr, &data, vme->am, cvD16);
   /* D32 */
   else if (vme->dmode == MVME_DMODE_D32)
      status = CAENVME_ReadCycle(hvme, vme_addr, &data, vme->am, cvD32);

   return data;
}

/*------------------------------------------------------------------*/

int mvme_set_am(MVME_INTERFACE *vme, int am)
{
   vme->am = am;
   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_get_am(MVME_INTERFACE *vme, int *am)
{
   *am = vme->am;
   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_set_dmode(MVME_INTERFACE *vme, int dmode)
{
   vme->dmode = dmode;
   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_get_dmode(MVME_INTERFACE *vme, int *dmode)
{
   *dmode = vme->dmode;
   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_set_blt(MVME_INTERFACE *vme, int mode)
{
   vme->blt_mode = mode;
   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/

int mvme_get_blt(MVME_INTERFACE *vme, int *mode)
{
   *mode = vme->blt_mode;
   return MVME_SUCCESS;
}

/*------------------------------------------------------------------*/
... 326 more lines ...
Attachment 4: v792n.h
/*********************************************************************

  Name:         v792n.h
  Created by:   Jimmy Ngai

  Contents:     V792N 16ch. QDC include

  Based on v792.h by Pierre-Andre Amaudruz

  $Id: $
*********************************************************************/
#ifndef  V792N_INCLUDE_H
#define  V792N_INCLUDE_H

#include <stdio.h>
#include <string.h>
#include "mvmestd.h"

#ifdef __cplusplus
extern "C" {
#endif

#define  V792N_MAX_CHANNELS       (DWORD) 16
#define  V792N_REG_BASE           (DWORD) (0x1000)
#define  V792N_FIRM_REV           (DWORD) (0x1000)
#define  V792N_GEO_ADDR_RW        (DWORD) (0x1002)
#define  V792N_MCST_CBLT_RW       (DWORD) (0x1004)
#define  V792N_BIT_SET1_RW        (DWORD) (0x1006)
#define  V792N_BIT_CLEAR1_WO      (DWORD) (0x1008)
#define  V792N_SOFT_RESET         (DWORD) (0x1<<7)
#define  V792N_INT_LEVEL_WO       (DWORD) (0x100A)
#define  V792N_INT_VECTOR_WO      (DWORD) (0x100C)
#define  V792N_CSR1_RO            (DWORD) (0x100E)
#define  V792N_CR1_RW             (DWORD) (0x1010)
#define  V792N_ADER_H_RW          (DWORD) (0x1012)
#define  V792N_ADER_L_RW          (DWORD) (0x1014)
#define  V792N_SINGLE_RST_WO      (DWORD) (0x1016)
#define  V792N_MCST_CBLT_CTRL_RW  (DWORD) (0x101A)
#define  V792N_EVTRIG_REG_RW      (DWORD) (0x1020)
#define  V792N_CSR2_RO            (DWORD) (0x1022)
#define  V792N_EVT_CNT_L_RO       (DWORD) (0x1024)
#define  V792N_EVT_CNT_H_RO       (DWORD) (0x1026)
#define  V792N_INCR_EVT_WO        (DWORD) (0x1028)
#define  V792N_INCR_OFFSET_WO     (DWORD) (0x102A)
#define  V792N_LD_TEST_RW         (DWORD) (0x102C)
#define  V792N_DELAY_CLEAR_RW     (DWORD) (0x102E)
#define  V792N_FCLR_WIN_RW        (DWORD) (0x102E)
#define  V792N_BIT_SET2_RW        (DWORD) (0x1032)
#define  V792N_BIT_CLEAR2_WO      (DWORD) (0x1034)
#define  V792N_W_MEM_TEST_WO      (DWORD) (0x1036)
#define  V792N_MEM_TEST_WORD_H_WO (DWORD) (0x1038)
#define  V792N_MEM_TEST_WORD_L_WO (DWORD) (0x103A)
#define  V792N_CRATE_SEL_RW       (DWORD) (0x103C)
#define  V792N_TEST_EVENT_WO      (DWORD) (0x103E)
#define  V792N_EVT_CNT_RST_WO     (DWORD) (0x1040)
#define  V792N_IPED_RW            (DWORD) (0x1060)
#define  V792N_R_MEM_TEST_WO      (DWORD) (0x1064)
#define  V792N_SWCOMM_WO          (DWORD) (0x1068)
#define  V792N_SLIDECONST_RW      (DWORD) (0x106A)
#define  V792N_AAD_RO             (DWORD) (0x1070)
#define  V792N_BAD_RO             (DWORD) (0x1072)
#define  V792N_THRES_BASE         (DWORD) (0x1080)

WORD v792n_Read16(MVME_INTERFACE *mvme, DWORD base, int offset);
void v792n_Write16(MVME_INTERFACE *mvme, DWORD base, int offset, WORD value);
DWORD v792n_Read32(MVME_INTERFACE *mvme, DWORD base, int offset);
void v792n_Write32(MVME_INTERFACE *mvme, DWORD base, int offset, DWORD value);

int  v792n_DataReady(MVME_INTERFACE *mvme, DWORD base);
int  v792n_isEvtReady(MVME_INTERFACE *mvme, DWORD base);
int  v792n_isBusy(MVME_INTERFACE *mvme, DWORD base);
int  v792n_EventRead(MVME_INTERFACE *mvme, DWORD base, DWORD *pdest, int *nentry);
int  v792n_DataRead(MVME_INTERFACE *mvme, DWORD base, DWORD *pdest, int nentry);
void v792n_DataClear(MVME_INTERFACE *mvme, DWORD base);
void v792n_EvtCntRead(MVME_INTERFACE *mvme, DWORD base, DWORD *evtcnt);
void v792n_EvtCntReset(MVME_INTERFACE *mvme, DWORD base);
void v792n_IntSet(MVME_INTERFACE *mvme, DWORD base, int level, int vector);
void v792n_IntEnable(MVME_INTERFACE *mvme, DWORD base, int level);
void v792n_IntDisable(MVME_INTERFACE *mvme, DWORD base);
void v792n_EvtTriggerSet(MVME_INTERFACE *mvme, DWORD base, int count);
void v792n_SingleShotReset(MVME_INTERFACE *mvme, DWORD base);
void v792n_SoftReset(MVME_INTERFACE *mvme, DWORD base);
void v792n_Trigger(MVME_INTERFACE *mvme, DWORD base);
int  v792n_ThresholdRead(MVME_INTERFACE *mvme, DWORD base, WORD *threshold);
int  v792n_ThresholdWrite(MVME_INTERFACE *mvme, DWORD base, WORD *threshold);
int  v792n_CSR1Read(MVME_INTERFACE *mvme, DWORD base);
int  v792n_CSR2Read(MVME_INTERFACE *mvme, DWORD base);
int  v792n_BitSet2Read(MVME_INTERFACE *mvme, DWORD base);
void v792n_BitSet2Set(MVME_INTERFACE *mvme, DWORD base, WORD pat);
void v792n_BitSet2Clear(MVME_INTERFACE *mvme, DWORD base, WORD pat);
WORD v792n_ControlRegister1Read(MVME_INTERFACE *mvme, DWORD base);
void v792n_ControlRegister1Write(MVME_INTERFACE *mvme, DWORD base, WORD pat);
void v792n_OnlineSet(MVME_INTERFACE *mvme, DWORD base);
void v792n_OfflineSet(MVME_INTERFACE *mvme, DWORD base);
void v792n_BlkEndEnable(MVME_INTERFACE *mvme, DWORD base);
void v792n_OverRangeEnable(MVME_INTERFACE *mvme, DWORD base);
void v792n_OverRangeDisable(MVME_INTERFACE *mvme, DWORD base);
void v792n_LowThEnable(MVME_INTERFACE *mvme, DWORD base);
void v792n_LowThDisable(MVME_INTERFACE *mvme, DWORD base);
void v792n_EmptyEnable(MVME_INTERFACE *mvme, DWORD base);
void v792n_CrateSet(MVME_INTERFACE *mvme, DWORD base, DWORD *evtcnt);
void v792n_DelayClearSet(MVME_INTERFACE *mvme, DWORD base, int delay);
int  v792n_Setup(MVME_INTERFACE *mvme, DWORD base, int mode);
void v792n_Status(MVME_INTERFACE *mvme, DWORD base);
int  v792n_isPresent(MVME_INTERFACE *mvme, DWORD base);

  enum v792n_DataType {
    v792n_typeMeasurement=0,
    v792n_typeHeader     =2,
    v792n_typeFooter     =4,
    v792n_typeFiller     =6
  };

  typedef union {
    DWORD raw;
    struct v792n_Entry {
      unsigned adc:12; // bit0 here
      unsigned ov:1;
      unsigned un:1;
      unsigned _pad_1:3;
      unsigned channel:4;
      unsigned _pad_2:3;
      unsigned type:3;
      unsigned geo:5;
    } data ;
    struct v792n_Header {
      unsigned _pad_1:8; // bit0 here
      unsigned cnt:6;
      unsigned _pad_2:2;
      unsigned crate:8;
      unsigned type:3;
      unsigned geo:5;
    } header;
    struct v792n_Footer {
      unsigned evtCnt:24; // bit0 here
      unsigned type:3;
      unsigned geo:5;
    } footer;
  } v792n_Data;

  typedef union {
    DWORD raw;
    struct {
      unsigned DataReady:1; // bit0 here
      unsigned GlobalDataReady:1;
      unsigned Busy:1;
      unsigned GlobalBusy:1;
      unsigned Amnesia:1;
      unsigned Purge:1;
      unsigned TermOn:1;
      unsigned TermOff:1;
      unsigned EventReady:1; //bit 8 here
    };
  } v792n_StatusRegister1;
  typedef union {
    DWORD raw;
    struct {
      unsigned _pad_1:1; // bit0 here
      unsigned BufferEmpty:1;
      unsigned BufferFull:1;
      unsigned _pad_2:1;
      unsigned PB:4;
      //unsigned DSEL0:1;
      //unsigned DSEL1:1;
      //unsigned CSEL0:1;
      //unsigned CSEL1:1;
    };
  } v792n_StatusRegister2;
  typedef union {
    DWORD raw;
    struct {
      unsigned _pad_1:2;
      unsigned BlkEnd:1;
      unsigned _pad_2:1;
      unsigned ProgReset:1;
      unsigned BErr:1;
      unsigned Align64:1;
    };
  } v792n_ControlRegister1;
  typedef union {
    DWORD raw;
    struct {
      unsigned MemTest:1;
      unsigned OffLine:1;
      unsigned ClearData:1;
      unsigned OverRange:1;
      unsigned LowThresh:1;
      unsigned _pad_1:1;//bit5
      unsigned TestAcq:1;
      unsigned SLDEnable:1;
      unsigned StepTH:1;
      unsigned _pad_2:2;//bits 9-10
      unsigned AutoIncr:1;
      unsigned EmptyProg:1;
      unsigned SlideSubEnable:1;
      unsigned AllTrg:1;
    };
  } v792n_BitSet2Register;

  void v792n_printEntry(const v792n_Data* v);

#ifdef __cplusplus
}
#endif

#endif // V792N_INCLUDE_H

/* emacs
 * Local Variables:
 * mode:C
 * mode:font-lock
 * tab-width: 8
 * c-basic-offset: 2
 * End:
 */
Attachment 5: v792n.c
/*********************************************************************

  Name:         v792n.c
  Created by:   Jimmy Ngai

  Contents:     V792N 16ch. QDC

  Based on v792.c by Pierre-Andre Amaudruz
                
  $Id: $
*********************************************************************/
#include <stdio.h>
#include <string.h>
#include <signal.h>
#if defined(OS_LINUX)
#include <unistd.h>
#endif
#include "v792n.h"

WORD v792n_Read16(MVME_INTERFACE *mvme, DWORD base, int offset)
{
  int cmode;
  WORD data;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  data = mvme_read_value(mvme, base+offset);
  mvme_set_dmode(mvme, cmode);
  return data;
}

void v792n_Write16(MVME_INTERFACE *mvme, DWORD base, int offset, WORD value)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+offset, value);
  mvme_set_dmode(mvme, cmode);
}

DWORD v792n_Read32(MVME_INTERFACE *mvme, DWORD base, int offset)
{
  int cmode;
  DWORD data;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D32);
  data = mvme_read_value(mvme, base+offset);
  mvme_set_dmode(mvme, cmode);
  return data;
}

void v792n_Write32(MVME_INTERFACE *mvme, DWORD base, int offset, DWORD value)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D32);
  mvme_write_value(mvme, base+offset, value);
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
int v792n_DataReady(MVME_INTERFACE *mvme, DWORD base)
{
  int data_ready, cmode;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  data_ready = mvme_read_value(mvme, base+V792N_CSR1_RO) & 0x1;
  mvme_set_dmode(mvme, cmode);
  return data_ready;
}

/*****************************************************************/
int v792n_isEvtReady(MVME_INTERFACE *mvme, DWORD base)
{
  int csr;
  csr = v792n_CSR1Read(mvme, base);
  return (csr & 0x100);
}

/*****************************************************************/
int v792n_isBusy(MVME_INTERFACE *mvme, DWORD base)
{
  int status, busy, timeout, cmode;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  timeout = 1000;
  do {
    status = mvme_read_value(mvme, base+V792N_CSR1_RO);
    busy = status & 0x4;
    timeout--;
  } while (busy || timeout);
  mvme_set_dmode(mvme, cmode);
  return (busy != 0 ? 1 : 0);
}

/*****************************************************************/
/*
Read single event, return event length (number of entries)
*/
int v792n_EventRead(MVME_INTERFACE *mvme, DWORD base, DWORD *pdest, int *nentry)
{
#define USE_BLT_READ_2

#ifdef USE_SINGLE_READ
  DWORD hdata;
  int   cmode;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D32);

  *nentry = 0;
  if (v792n_DataReady(mvme, base)) {
    do {
      hdata = mvme_read_value(mvme, base);
    } while (!(hdata & 0x02000000)); // skip up to the header

    pdest[*nentry] = hdata;
    *nentry += 1;
    do {
      pdest[*nentry] = mvme_read_value(mvme, base);
      *nentry += 1;
    } while (!(pdest[*nentry-1] & 0x04000000)); // copy until the trailer

    nentry--;
  }

  mvme_set_dmode(mvme, cmode);
#endif // USE_SINGLE_READ

#ifdef USE_BLT_READ_1
  DWORD hdata, data[V792N_MAX_CHANNELS+2];
  int   cam, cmode, cblt, cnt, i;

  mvme_get_am(mvme, &cam);
  mvme_get_dmode(mvme, &cmode);
  mvme_get_blt(mvme, &cblt);
  mvme_set_dmode(mvme, MVME_DMODE_D32);

  *nentry = 0;
  if (v792n_DataReady(mvme, base)) {
    do {
      hdata = mvme_read_value(mvme, base);
    } while (!(hdata & 0x02000000)); // skip up to the header

    mvme_set_am(mvme, MVME_AM_A32_SB);
    mvme_set_blt(mvme, MVME_BLT_BLT32);
    cnt = (hdata >> 8) & 0x3F;

    mvme_read(mvme, data, base, (cnt+1)*4);
    pdest[0] = hdata;
    for (i=1;i<=cnt+1;i++)
      pdest[i] = data[i-1];

    *nentry = cnt + 2;
  }

  mvme_set_am(mvme, cam);
  mvme_set_dmode(mvme, cmode);
  mvme_set_blt(mvme, cblt);
#endif // USE_BLT_READ_1

#ifdef USE_BLT_READ_2
  int   cam, cmode, cblt, cnt;

  mvme_get_am(mvme, &cam);
  mvme_get_dmode(mvme, &cmode);
  mvme_get_blt(mvme, &cblt);
  mvme_set_dmode(mvme, MVME_DMODE_D32);

  *nentry = 0;
//  if (v792n_DataReady(mvme, base)) {
    mvme_set_am(mvme, MVME_AM_A32_SB);
    mvme_set_blt(mvme, MVME_BLT_BLT32);
    mvme_read(mvme, pdest, base, (V792N_MAX_CHANNELS+2)*4);
    cnt = (pdest[0] >> 8) & 0x3F;
    *nentry = cnt + 2;
//  }

  mvme_set_am(mvme, cam);
  mvme_set_dmode(mvme, cmode);
  mvme_set_blt(mvme, cblt);
#endif //USE_BLT_READ_2

  return *nentry;
}

/*****************************************************************/
/*
Read nentry of data from the data buffer
*/
int v792n_DataRead(MVME_INTERFACE *mvme, DWORD base, DWORD *pdest, int nentry)
{
  int  cmode, status;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D32);
//  nentry = 128;
  if (v792n_DataReady(mvme, base)) {
    status = mvme_read(mvme, pdest, base, nentry*4);
  }
  mvme_set_dmode(mvme, cmode);
  return status;
}

/*****************************************************************/
void v792n_DataClear(MVME_INTERFACE *mvme, DWORD base)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_BIT_SET2_RW, 0x4);
  mvme_write_value(mvme, base+V792N_BIT_CLEAR2_WO, 0x4);
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_EvtCntRead(MVME_INTERFACE *mvme, DWORD base, DWORD *evtcnt)
{
  int cmode;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  *evtcnt  = mvme_read_value(mvme, base+V792N_EVT_CNT_L_RO);
  *evtcnt += (mvme_read_value(mvme, base+V792N_EVT_CNT_H_RO) << 16);
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_EvtCntReset(MVME_INTERFACE *mvme, DWORD base)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_EVT_CNT_RST_WO, 1);
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_IntSet(MVME_INTERFACE *mvme, DWORD base, int level, int vector)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_INT_VECTOR_WO, (vector & 0xFF));
  mvme_write_value(mvme, base+V792N_INT_LEVEL_WO, (level & 0x7));
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_IntEnable(MVME_INTERFACE *mvme, DWORD base, int level)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_EVTRIG_REG_RW, (level & 0x1F));
  /* Use the trigger buffer for int enable/disable
  mvme_write_value(mvme, base+V792N_INT_LEVEL_WO, (level & 0x7));
  */
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_IntDisable(MVME_INTERFACE *mvme, DWORD base)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_EVTRIG_REG_RW, 0);
  /* Use the trigger buffer for int enable/disable
     Setting a level 0 reboot the VMIC !
  mvme_write_value(mvme, base+V792N_INT_LEVEL_WO, 0);
  */
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_EvtTriggerSet(MVME_INTERFACE *mvme, DWORD base, int count)
{
  int cmode;

  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_EVTRIG_REG_RW, (count & 0x1F));
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
void v792n_SingleShotReset(MVME_INTERFACE *mvme, DWORD base)
{
  int cmode;
  mvme_get_dmode(mvme, &cmode);
  mvme_set_dmode(mvme, MVME_DMODE_D16);
  mvme_write_value(mvme, base+V792N_SINGLE_RST_WO, 1);
  mvme_set_dmode(mvme, cmode);
}

/*****************************************************************/
... 409 more lines ...
  760   10 May 2011 Pierre-Andre AmaudruzForumsimple example frontend for V1720

Jianglai Liu wrote:
Hi,

Who has a good example of a frontend program using CAEN V1718 VME-USB bridge and
V1720 FADC? I am trying to set up the DAQ for such a simple system.

I put together a frontend which talks to the VME. However it gets stuck at
"Calibrating" in initialize_equipment().

I'd appreciate some help!

Thanks,
Jianglai


Under the drivers/vme you can find code for the v1720.c (VME access) and ov1720.c
(A2818/A3818 PCIe optical link access). For testing the hardware, we use this code compiled and linked
with MAIN_ENABLE to confirm its functionality. You may want to do the same for your USB. Once this
is under control, the Midas frontend implementation using the same driver shouldn't give you trouble.
  759   10 May 2011 Stefan RittForumsimple example frontend for V1720

Jianglai Liu wrote:
Hi,

Who has a good example of a frontend program using CAEN V1718 VME-USB bridge and
V1720 FADC? I am trying to set up the DAQ for such a simple system.

I put together a frontend which talks to the VME. However it gets stuck at
"Calibrating" in initialize_equipment().

I'd appreciate some help!

Thanks,
Jianglai


During "Calibrating", the framework calls your poll_event() routine. You code there accesses for the first time the VME crate and probably gets stuck.
  758   10 May 2011 Jianglai LiuForumsimple example frontend for V1720
Hi,

Who has a good example of a frontend program using CAEN V1718 VME-USB bridge and
V1720 FADC? I am trying to set up the DAQ for such a simple system.

I put together a frontend which talks to the VME. However it gets stuck at
"Calibrating" in initialize_equipment().

I'd appreciate some help!

Thanks,
Jianglai
  757   15 Apr 2011 Konstantin OlchanskiForumHow large does "bank32" support?
> Reading an FADC buffer often needs large buffer size, especially while several
> FADCs work together. I want to know how large a bank32 can support.

Limitations in order:

- bank32 size is limited to a 32 bit integer size (about 4000 Gbytes)
- bank size is limited by event size
- event size in a midas mfe.c based frontend is limited to the value of
max_event_size set by the user
- maximum event size that can go through the MIDAS event buffer system is limited
to ODB value /Experiment/MAX_EVENT_SIZE (MAX_EVENT_SIZE in midas.h does not do
anything now)
- maximum event size is limited to *half* the size of the SYSTEM shared memory
event buffer (or any other buffers that the event has to go through)
- default size of the SYSTEM buffer is 8 Mbytes set by ODB /Experiment/Buffer
sizes/SYSTEM. This limits maximum event size to about 4 Mbytes.
- size of SYSTEM buffer can be increased to arbitrary size, but in practice no
bigger than the amount of computer physical memory minus space needed for running
the frontend program and the mlogger, which also allocate buffer space to hold 1
event of maximum size.

So for a computer with 8 Gbytes of RAM, you can make the SYSTEM buffer size 4
GBytes, set ODB MAX_EVENT_SIZE to 1 Gbyte, and in theory, you should be able to
write 1 Gbyte events from your frontend to disk.

In practice, I think the biggest events I have seen go through a MIDAS system are
non-compressed waveforms in the T2K/ND280 FGD and TPC detectors, about 4 Mbytes of
data per event.

Other considerations (rules of thumb):

1) the SYSTEM event buffer should be big enough to hold 10-100 events.
2) the SYSTEM event buffer should be big enough to hold about 5-10 seconds of data
- i.e. if your event size is 1 Mbyte and data rate is 1 Hz, 10 seconds of data
will be 1Mbyte*1Hz*10sec = 10 Mbytes.

This is because the SYSTEM buffer decouples the real-time activity of the frontend
program from non-real-time activity of writing data to storage devices.

K.O.
ELOG V3.1.4-2e1708b5