esrf

Beamline Instrument Software Support
SPEC Macro documentation: [ Macro Index | BCU Home ]

#%TITLE% opiomtools.mac
#%DESCRIPTION%
#  Utility macro to generate gate/pulses/counter with default opiom prog.
#%END%


def opiom_pulse_on '{
    global OPIOM_PULSE[]
    if ($#!=2) {
	print "Usage: $0 [output] [frequency (Hz)]"
	exit
    }
    OPIOM_PULSE[int($1)]= $2 * 1.0
    cdef("user_prepcount", "_opiom_pulse_precount;\n", "_oppl_", 0x20)
    cdef("user_countersrun", "_opiom_pulse_runcount;\n", "_oppl_", 0x10)
}'

def opiom_pulse_off '{
    cdef("", "", "delete", "_oppl_")
    unglobal OPIOM_PULSE
}'

#%IU%
def _opiom_pulse_precount '{
    global OPIOM_PULSE_TIME
    local chans[] nchan ichan ctms delay

    ctms= int(COUNT_TIME*1000.)
    nchan= 0
    OPIOM_PULSE_TIME= 0
    for (ichan in OPIOM_PULSE) {
	freq= OPIOM_PULSE[ichan]
	npulse= int(COUNT_TIME / freq * 1.1)
	delay= 1000./freq/2.
	_opiom_pulse(ichan, delay, delay, npulse)
	total= delay * 2. * npulse
	if (total > OPIOM_PULSE_TIME)
	    OPIOM_PULSE_TIME= total
    	chans[nchan]= ichan
        nchan+= 1
    }
    _opiom_start(nchan, chans)
    OPIOM_PULSE_TIME= time() + OPIOM_PULSE_TIME/1000.
}'

#%IU%
def _opiom_pulse_runcount '
    if (time() <= OPIOM_PULSE_TIME)
	return (1)
'

#%UU% [output] ([delay (ms)])
#%MDESC%
# Activate gate on "ct" for specified output
#%BR% Several gates might be configured
def opiom_gate_on '{
    global OPIOM_GATE[]
    local chan
    if (($# != 1)&&($# != 2)) {
	print "Usage: $0 [output] ([delay (ms)])"
	exit
    }
    OPIOM_GATE[int($1)]= int($2)
    cdef("user_prepcount", "_opiom_gate_precount;\n", "_opga_", 0x20)
    cdef("user_countersrun", "_opiom_gate_runcount;\n", "_opga_", 0x10)
}'

#%UU% 
#%MDESC%
# Unconfigure all gates
#
def opiom_gate_off '{
    cdef("", "", "delete", "_opga_")
    unglobal OPIOM_GATE
}'

#%UU%
#%MDESC%
# Show list of output configured as gate on ct
#
def opiom_gate_show '{
    if (whatis("OPIOM_GATE")&0x04000000) {
        local ichan
    
        printf("== OPIOM GATE on COUNTs ==\n")
        for (ichan in OPIOM_GATE) 
	    printf(" - O%d [delay %d ms]\n", ichan, OPIOM_GATE[ichan])
        print
    } else {
	printf("== NO OPIOM GATE defined !!\n")
    }
}'

#%IU%
def _opiom_gate_precount '{
    global OPIOM_GATE_TIME
    local chans[] nchan ichan ctms delay
    delay= 0
    ctms= int(COUNT_TIME*1000.)
    nchan= 0
    for (ichan in OPIOM_GATE) {
	_opiom_pulse(ichan, OPIOM_GATE[ichan], ctms, 1)
    	if (OPIOM_GATE[ichan]>delay)
	    delay= OPIOM_GATE[ichan]
    	chans[nchan]= ichan
        nchan+= 1
    }
    _opiom_start(nchan, chans)
    OPIOM_GATE_TIME= time() + (ctms+delay)/1000.
}'

#%IU%
def _opiom_gate_runcount '
    if (time() <= OPIOM_GATE_TIME)
	return (1)
'

#%UU% [output] [delay (ms)] [width (ms)]
#%MDESC%
# Generates a gate on specified output.
# No start is needed : gate is generated on macro execution.
def opiom_gate '{
    local chs[]
    if ($# != 3) {
	    print "Usage: $0 [output] [delay (ms)] [width (ms)]"
	    exit
    }
    chan[0]= int($1)
    _opiom_pulse(chan[0], int($2), int($3), 1)
    _opiom_start(1, chan)
}'

#%UU% [output] [delay (ms)] [width (ms)] [nb_pulse]
#%MDESC%
# Generate pulse(s) on specified output.
# To really start pulses generation, %B%opiom_start%B% has to be executed.
# Multiple output can be configured with different settings and all can be
# started with %B%opiom_start%B%
#
def opiom_pulse '{
    if ($# != 4) {
		print "Usage: $0 [output] [delay (ms)] [width (ms)] [nb_pulse]"
		exit
	}
	_opiom_pulse(int($1), $2, $3, int($4))
}'

#%IU%
def _opiom_pulse(output, delay, width, nbpulse) '{
	local opdelay opwidth oppulse

	# 2MHz clock, parameters in ms
	opdelay= delay>0 ? int(delay*2000) : 1
	opwidth= width>0 ? int(width*2000) : 1
	oppulse= nbpulse>0 ? nbpulse : 1

	comm= sprintf("CNT %d RESET\r", output)
	isgdevice_comm_ack(OPIOM_AUX["default"], comm)
	comm= sprintf("CNT %d CLK2 PULSE %d %d %d\r", output, opwidth, opdelay, oppulse)
	isgdevice_comm_ack(OPIOM_AUX["default"], comm)
}'

#%UU% [list_of_output]
#%MDESC%
# Start generating specified output(s). They need to be configured with
# %B%opiom_pulse%B%.
#
def opiom_start '{
	local npar pars[]

	if (!$#) {
		print "Usage: $0 [list_of_output]"
		exit
	}

	npar= split("$*", pars)
	_opiom_start(npar, pars)
}'

#%UU% [list_of_output]
#%MDESC%
# Stop all output
#
def opiom_stop '{
	local npar pars[]

	if (!$#) {
		print "Usage: $0 [list_of_output]"
		exit
	}

	npar= split("$*", pars)
	_opiom_stop(npar, pars)
}'

#%IU%
def _opiom_start(npar, pars) '{
	_opiom_chan_comm("START", npar, pars)
}'

#%IU%
def _opiom_stop(npar, pars) '{
	_opiom_chan_comm("STOP", npar, pars)
}'

#%IU%
def _opiom_chan_comm(cmd, npar, pars) '{
	local ipar res comm
	for (ipar=0,res=0; ipar<npar; ipar++)
		res |= (1<<(pars[ipar]-1))

	comm= sprintf("%s %d\r", cmd, res)
	isgdevice_comm_ack(OPIOM_AUX["default"], comm)
}'

#%UU% [input] [counter]
#%MDESC%
# Configure a counter (1 to 4) on specified input (1 to 8)
#
def opiom_counter '{
	if ($# != 2) {
		print "Usage: $0 [input] [counter]"
		exit
	}

	_opiom_counter(int($1), int($2))
}'

#%IU%
def _opiom_counter(ichan, cnt) '{
	local iclk[]
	iclk[1]= "CLKA"
	iclk[2]= "CLKB"
	iclk[3]= "CLKC"
	iclk[4]= "CLKD"

	comm= sprintf("CNT %d RESET\r", cnt)
	isgdevice_comm_ack(OPIOM_AUX["default"], comm)
	comm= sprintf("CNT %d %s COUNT\r", cnt, iclk[ichan])
	isgdevice_comm_ack(OPIOM_AUX["default"], comm)
}'

#%UU%
#%MDESC%
# Get values of previously configured counters
#
def opiom_getval '{
	local ipar npar pars[]

	if (!$#) {
		print "Usage: $0 [list_of_counters]"
		exit
	}

	npar= split("$*", pars)
	for (ipar=0; ipar<npar; ipar++)
		printf("CNT%d = %g\n", pars[ipar], _opiom_getval(pars[ipar]))
}'

#%IU%
def _opiom_getval(icnt) '{
	local comm
	comm= sprintf("?VCNT %d\n", icnt)
	val= isgdevice_comm(OPIOM_AUX["default"], comm)
	return int(val)
}'

#%MACROS%
#%IMACROS%
#%TOC%
#%AUTHOR% E.Papillon, $Revision: 1.2 $, $Date: 2016/06/15 08:34:36 $