Commit a8a0c4e0 authored by Oscar Gargiulo's avatar Oscar Gargiulo
Browse files

let's pray it works forgot what i changed anyway

parent 95279ef0
......@@ -37,4 +37,5 @@ IPList = {'SCOPE': '192.168.0.99',
'SA2': '192.168.0.140',
'XXF1': '138.232.183.115', # Running on Windows machine
'NI6020': '138.232.183.115' # Running on Windows machine
#'DA': '192.168.0.119' #does not work with vxi, use socets instead
}
# -*- coding: utf-8 -*-
"""
Created on Mon May 6 14:01:41 2019
@author: User
"""
import vxi11
class dig_at_mc(vxi11.Instrument):
def __init__(self,ip='192.168.0.119'):
super(dig_at_mc, self).__init__(ip)
def com(self, command, arg="?"):
"""Function to communicate with the device. Gives the current status
if no arg is given
Parameters
-----------
command : str
Command/Query string for device
arg : str, int, float
Argument for command
"""
if arg == "?":
try:
return float(self.ask("{}?\n".format(command)))
except:
return self.ask("{}?\n".format(command))
else:
self.write("{} {}\n".format(command, arg))
return None
'''
def reset(self):
self.com('*RST', '')
def connect(self,board_num=1):
'''
\ No newline at end of file
......@@ -5,6 +5,14 @@ Created on Mon Oct 20 10:32:12 2014
@author: Oscar
wrapper class for the SDR14 library
v2.0.2 - OSC:
- implemented the connection to different boards when more than one is in the chassis
v2.0.1 - OSC:
- bugfix in edge setting for ext trigger in dig class
v2.0.0 - OSC:
- adapted to python dictionary
v1.1.2 - OSC:
inserted conv_factor to convert digits to V (it is a constant, must multiply digits for it)
......@@ -17,47 +25,67 @@ modified the function used to setup the averaging mode
"""
print('SDR14 library v1.1.2')
class SDR14(object):
import ctypes as ct
import numpy as np
version='1.1.1'
def __init__(self,OS='LINUX'):
self.DACSF = 1.6 #Gigasamples/s
self.ADCSF= 0.8 #Gigasamples/s
self.conv_factor = 2.2/(2**16-1)
if OS=='LINUX':
version='2.0.2'
def __init__(self,OS='WINDOWS',board_num = 1):
if OS.upper()=='LINUX':
self.ADQAPI = self.ct.cdll.LoadLibrary("libadq.so")
else:
elif OS.upper()=='WINDOWS':
self.ADQAPI = self.ct.cdll.LoadLibrary("ADQAPI.dll")
else:
print('Wrong OS inserted: {LINUX,WINDOWS}\n')
return None
self._PXITrig0=0
self._PXITrig1=0
#some c language configuration
self.ADQAPI.CreateADQControlUnit.restype = self.ct.c_void_p
self.ADQAPI.ADQ_GetRevision.restype = self.ct.c_void_p
self.ADQAPI.ADQControlUnit_FindDevices.argtypes = [self.ct.c_void_p]
self.ADQAPI.ADQ_GetPtrStream.restype = self.ct.c_void_p#self.ct.POINTER(self.ct.c_int16)
self.connect()
self.connect(board_num)
def connect(self):
def connect(self,board_num=1):
self._sdr = self.ct.c_void_p(self.ADQAPI.CreateADQControlUnit())
self.ADQAPI.ADQControlUnit_FindDevices(self._sdr)
self.DEV_NUM=self.ADQAPI.ADQControlUnit_NofSDR14(self._sdr)
DEV_NUM=self.ADQAPI.ADQControlUnit_NofSDR14(self._sdr)
if self.DEV_NUM==0:
if DEV_NUM==0:
print("WARNING: No device has been found")
return 0
board_num = int(board_num)
if board_num <0:
print('Error: board_num can\'t be negative!')
return 0
if board_num > DEV_NUM:
print("Erro: Selected board number {}, but only {} boards have been found!".format(board_num,DEV_NUM))
return 0
self.__devnum = board_num
self.clock_ref() #ext ref activated by def
self.dig = self._DIG(self.ADQAPI,self._sdr,board_num)
self.awg = self._AWG(self.ADQAPI,self._sdr,board_num) #not fully implemented yet
self.dig.gainandoffset(1,1,301) #ch1 offset fix (calibration)
self.dig.gainandoffset(2,1,361) #ch2 offset fix (calibration)
return 1
def disconnect(self):
self.ADQAPI.DeleteADQControlUnit(self._sdr)
self._sdr=None
self._sdr= None
self.dig = None
def reset(self,Type='COMM'):
'''function reset([Type='COMM']):
......@@ -68,911 +96,1090 @@ class SDR14(object):
if type(Type) is str:
if Type.upper()=='COMM':
return self.ADQAPI.ADQ_ResetDevice(self._sdr,1,8)
return self.ADQAPI.ADQ_ResetDevice(self._sdr,self.__devnum,8)
elif Type.upper()=='TOT':
return self.ADQAPI.ADQ_ResetDevice(self._sdr,1,2)
return self.ADQAPI.ADQ_ResetDevice(self._sdr,self.__devnum,2)
else:
print('Wrong Type inserted')
return 0
else:
if Type==1:
return self.ADQAPI.ADQ_ResetDevice(self._sdr,1,2)
return self.ADQAPI.ADQ_ResetDevice(self._sdr,self.__devnum,2)
else:
print('Wrong Type inserted')
return 0
"""
def bypass(self,Activate=False):
'''function bypass([Activate=False]):
This function will activate or deactivare the internal bypass from the DAC to the ADC:
Activate can be False (def) for normal operation or True (or 1) for the bypass
'''
if Activate==True or Activate==1:
data=1
else:
data=0
return self.ADQAPI.ADQ_WriteRegister(self._sdr, 1,10240,0xFFFFFFFE,data)
"""
#---- sd01 ---------------------------------------------------------------------------------------------------
# INPUT CHECK FUNCTIONS
def __typecheck(self,Type,Typelist,Min,Max):
if type(Type) is str:
try:
num=Typelist.index(Type.upper() )+1
except:
print('Wrong Type inserted')
return 'Err'
return None
else:
num=int(Type)
if num<Min or num>Max:
print('Wrong Type number inserted')
return 'Err'
return None
return num
return num
#--- sd02 ------------------------------------------------------------------------------------------------
# TRIGGER FUNCTIONS
def PXItrigger(self,Type='ACQ',Number=0,Direction=0):
'''function PXItrigger(Type='ACQ',Number=0,Direction=0)
This function can be used to set the first two PXI triggers.
ars:
Type: 'ACQ' or 'AWG' to set the trigger for the acquisition or the AWG
number: 0,1 (def 0) to choose the trigger number
direction: 'in' or 0 ,'out' or 1 to read or write a trigger
'''
if type(Type )==str:
if Type.upper()=='ACQ':
Type=0
elif Type.upper()=='AWG':
Type=1
else:
print('Wrong Type iserted: \'ACQ\' or \'AWG\'')
raise Exception('TYPEERR')
if Number==0:
bitflags = 1<<2
elif Number==1:
bitflags = 1<<3
else:
print('Wrong PXI trigger number iserted: 0 or 1')
raise Exception('NUMERR')
direction_type=['IN','OUT']
Direction = self.__typecheck(Direction,direction_type,0,1)
if Direction=='Err':
print('Wrong Direction inserted')
raise Exception('DIRERR')
if Number==0 :
self._PXITrig0 = Direction
else:
self._PXITrig1 = Direction
if self.ADQAPI.ADQ_SetPXIeTrigDirection(self._sdr,1,self._PXITrig0,self._PXITrig1)==0:
print('ERROR in setting the PXI trigger direction')
raise Exception('PXITRIGDIR')
if self.ADQAPI.ADQ_EnablePXIeTriggers(self._sdr,1,Type,bitflags)==0:
print('ERROR in enabling the PXI trigger')
raise Exception('PXITRIGEN')
def trigger_channel(self,Channel=None):
'''Function trigger_channel([Channel=None]):
This function is used to set the specified channel as a trigger:
Channel can be:
- 0 (no channel, internal trigger)
- 1 or 'A'
- 2 or 'B'
- None (def) the trigger channel will be queried
'''
if Channel is None:
return self.ADQAPI.ADQ_GetLvlTrigChannel(self._sdr,1)
else:
chan_types=['A','B']
ch=self.__typecheck(Channel,chan_types,0,2)
if ch=='Err':
return 0
if self.ADQAPI.ADQ_SetLvlTrigChannel(self._sdr,1,ch) == 0:
print('ERROR in setting the channel as a trigger')
raise Exception('TrigChan')
def trigger_mode(self,Type='SFT',*args):
'''function trigger_mode(Type='SFT'):
This function is used to set the trigger mode, Type can be:
- 'SFT' or 1 for software controlled trigger
- 'EXT' or 2 for external trigger 1
- further option:
- 0 for falling edge
- 1 for rising edge (def)
- 'LVL' or 3 for level trigger mode
- 'INT' or 4 for internal trigger
-further option: frequency of the internal trigger in Hz (def is sampling frequency / 4 )
- 'PXI' or 5 for the PXIe trigger (use the proper function to enable it)'''
trig_type=['SFT','EXT','LVL','INT','PXI']
trg=self.__typecheck(Type,trig_type,1,5)
if trg== 'Err':
return 0
if trg==5:
trg=6
if self.ADQAPI.ADQ_SetTriggerMode(self._sdr,1,trg)==0:
print('ERROR in setting the trigger mode')
raise Exception('TrigMode')
if trg==2:
if len(args)>0:
if args[0]==0 or args[0]==1:
return self.ADQAPI.ADQ_SetExternTrigEdge(self._sdr,1,args[0])
else:
print('Wrong EXT trigger edge inserted')
raise Exception('TrigType')
else:
if self.ADQAPI.ADQ_SetExternTrigEdge(self._sdr,1,1)==0:
print('ERROR in setting the External trigger')
raise Exception('EXTTrig')
if trg==4:
freq=int(args[0])
if freq<=0:
print('Wrong trigger frequency inserted')
raise Exception('TrigFreq')
if freq>=self.ADCSF*1e9:
print('trigger frequency too high')
raise Exception('TrigFreq')
if self.ADQAPI.ADQ_SetInternalTriggerFrequency(self._sdr,1,freq)==0:
print('Error in setting the trigger mode')
raise Exception('TrigMode')
def trigarm(self,Mode='ON'):
modtype=['OFF','ON']
mt=self.__typecheck(Mode,modtype,0,1)
if mt==0:
if self.ADQAPI.ADQ_DisarmTrigger(self._sdr,1) ==0:
print('ERROR in disarming the trigger')
raise Exception('TrigDisarm')
else:
if self.ADQAPI.ADQ_ArmTrigger(self._sdr,1)==0:
print('ERROR in arming the trigger')
raise Exception('TrigArm')
def trigwaiting(self):
return self.ADQAPI.ADQ_GetWaitingForTrigger(self._sdr,1)
def trigdelay(self,Time=0):
""" function trigdelay([Time = 0 ns])
This function will set the delay between the trigger and the begin of acquisition, in ns
"""
if Time<0:
print('Time cannot be negative')
raise Exception('NegTime')
ns=Time*self.ADCSF
if ns>2**31:
print('Time delay too large, max: '+str(2**31/self.ADCSF))
raise Exception('LargeDelayTime')
return self.ADQAPI.ADQ_SetTriggerHoldOffSamples(self._sdr,1,int(Time*self.ADCSF))
def trigger(self):
'''function trigger():
This function will software-trigger the board'''
if self.ADQAPI.ADQ_SWTrig(self._sdr,1) == 0:
print('Error in triggering the device')
raise Exception('TrigEXC')
#----sd03 -----------------------------------------------------------------------------------------------
# CLOCK FUNCTIONS
def DIGSF(self):
"""Returns the digitizer sampling frequency in GSamples/s"""
return 0.8 #GSamples/s
def AWGSF(self):
"""Returns the AWG sampling frequency in GSamples/s"""
return 1.6 #GSamples/s
def clock_ref(self,Type='EXTC'):
''' function clock_ref(self,Type='EXTC'):
This function will set the clock reference, Type can be:
- 'INT' or 1
- 'EXT' or 2
- 'EXTC' or 3 (def)
- 'INT' or 1 - for the internal clock
- 'EXT' or 2 - for an external clock
- 'EXTC' or 3 (def) - for a 10 MHZ clock sync. signal
'''
ref_types=['INT','EXT','EXTC']
num=self.__typecheck(Type,ref_types,0,2)-1
if num=='Err':
return 0
if num is None:
raise Exception(ValueError)
if num==2:
num=3
if self.ADQAPI.ADQ_SetClockSource(self._sdr,1,num)==0:
if self.ADQAPI.ADQ_SetClockSource(self._sdr,self.__devnum,num)==0:
print('ERROR in setting the clock reference')
raise Exception('ClockRef')
#---sd04 ------------------------------------------------------------------------------------------------
# acquisition functions
def GainOffset(self,Channel=1,Gain=None,Offset=None):
"""function GainOffset([Gain=None],[Offset=None])
This function can be used to set the ADC Gain and Offset of the specified Channel, in no argument is given, the value will be returned
"""
if Channel<1 or Channel>3:
print('Error: Wrong channel inserted')
raise Exception('ChannelNum')
if Gain == None or Offset ==None:
value_type = self.ct.c_int32*1
t1,t2 = value_type(0), value_type(0)
g,o= [],[]
if self.ADQAPI.ADQ_GetGainAndOffset(self._sdr,1,1,t1,t2)==0:
print('Error in getting Gain and Offset values')
raise Exception('GainOffsetRead')
g.append(int(t1[0])),o.append(int(t2[0]))
if self.ADQAPI.ADQ_GetGainAndOffset(self._sdr,1,2,t1,t2)==0:
print('Error in getting Gain and Offset values')
raise Exception('GainOffsetRead')
g.append(int(t1[0])),o.append(int(t2[0]))
#----- DIGCL00 --------------------------------------------------------------------------------------------
if Gain != None:
if Gain<-30 or Gain>30:
print("Error, wrong gain: -30 < Gain < 30")
raise Exception("GainValue")
class _DIG(object):
import ctypes as ct
import numpy as np
def __init__(self,library,board,devnum):
Gain*=1024
self.__ADCSF= 0.8 #Gigasamples/s
self.__conv_factor = 2.2/(2**16-1)
self.__max_digfreq = 400 #MHz
self.__max_digamp = 1.1 #Vp
if Offset != None:
if Channel == 3:
if self.ADQAPI.ADQ_SetGainAndOffset(self._sdr,1,1,Gain,Offset)==0:
print('Error in setting Gain and Offset values')
raise Exception('GainOffsetWrite')
self._trig_type=['SW','EXT','LVL','INT','','PXI']
self._trig_edge=['FALLING','RISING']
self._acq_mode=['MR','AVE']
self.__lib = library
self.__board = board
self.__devnum = devnum
self.pars_dict= {'TriggerMode':'SW',
'TriggerOptions': None,
'AcquisitionDelay': 0,
'AcquisitionMode': None,
'Records': 1,
'Samples': 1024,
'ChannelUsed': 3,
'Autoset':True
}
#----- DIGCL01 ----------------------------------------------------------------------- Checks and Exceptions
def __typecheck(self,Type,Typelist,Min,Max):
if type(Type) is str:
Type= Type.upper()
try:
num=Typelist.index(Type)+Min
except:
return None
else:
num=int(Type)
if num<Min or num>Max:
return None
return num
class __BASEEXC(Exception):
pass
class __DIGEXC(__BASEEXC):
def __init__(self, expression, message):
self.expression = expression
self.message = message
#------- DIGCL02 ---------------------------------------------------------------------- Gain and offset
def gainandoffset(self,Channel=1,Gain=None,Offset=None):
"""function GainOffset([Gain=None],[Offset=None])
This function can be used to set the ADC Gain and Offset of the
specified Channel {1,2}.
If no argument is given, the value will be returned.
Gain is [-30,30]
"""
"""because of a bug, gain and offsets for channel 1 must be executed on channel 1 and 2.
gain and offsets for channel 2 must be executed on channel 3 and 4"""
if Channel<1 or Channel>2:
raise self.__DIGEXC('ChannelNum','Error: Wrong channel inserted')
if Gain == None or Offset == None:
value_type = self.ct.c_int32*1
t1,t2 = value_type(0), value_type(0)
g,o= [],[]
if self.__lib.ADQ_GetGainAndOffset(self.__board,self.__devnum,Channel,t1,t2)==0:
raise self.__DIGEXC('GainOffsetRead','Error in getting Gain and Offset values')
g,o = int(t1[0]),int(t2[0])
del t1,t2
if self.ADQAPI.ADQ_SetGainAndOffset(self._sdr,1,2,Gain,Offset)==0:
print('Error in setting Gain and Offset values')
raise Exception('GainOffsetWrite')
else:
if self.ADQAPI.ADQ_SetGainAndOffset(self._sdr,1,Channel,Gain,Offset)==0:
print('Error in setting Gain and Offset values')
raise Exception('GainOffsetWrite')
loop_indexes = self.np.array([0,1])+2*(Channel-1)+1 #1 and 2 for Channel 1, 3 and 4 for Channel 2
if Gain != None:
if Gain<-30 or Gain>30:
raise self.__DIGEXC("GainValue","Error, wrong gain: -30 < Gain < 30")
Gain= int(Gain*1024)
if Offset != None:
for i in loop_indexes:
if self.__lib.ADQ_SetGainAndOffset(self.__board,self.__devnum,int(i),Gain,Offset)==0:
raise self.__DIGEXC('GainOffsetWrite','Error in setting Gain and Offset values')
else:
for i in loop_indexes:
if self.__lib.ADQ_SetGainAndOffset(self.__board,self.__devnum,int(i),Gain,o)==0: #Offset is unchanged
raise self.__DIGEXC('GainOffsetWrite','Error in setting Gain and Offset values')
else:
if Channel == 3:
if self.ADQAPI.ADQ_SetGainAndOffset(self._sdr,1,1,Gain,o[0])==0:
print('Error in setting Gain and Offset values')
raise Exception('GainOffsetWrite')
if self.ADQAPI.ADQ_SetGainAndOffset(self._sdr,1,2,Gain,o[1])==0:
print('Error in setting Gain and Offset values')
raise Exception('GainOffsetWrite')
else:
if self.ADQAPI.ADQ_SetGainAndOffset(self._sdr,1,Channel,Gain,o[Channel-1])==0:
print('Error in setting Gain and Offset values')
raise Exception('GainOffsetWrite')
if Offset is None:
return g,o
else:
for i in loop_indexes:
if self.__lib.ADQ_SetGainAndOffset(self.__board,self.__devnum,Channel,g,Offset)==0: #gain is unchanged
raise self.__DIGEXC('GainOffsetWrite','Error in setting Gain and Offset values')
#----- DICCL03 ------------------------------------------------------------------ parameters functions ------------
def autoset(self,arg=None):
if arg is None:
return self.pars_dict['Autoset']
if arg is True or arg is 1:
self.pars_dict['Autoset'] = True
elif arg is False or arg is 0:
self.pars_dict['Autoset'] = False
else:
raise self.__DIGEXC('Autoset','Wrong value inserted: {}'.format(arg)+'/{True,False}')
def trigger_mode(self,Mode=None,arg=None):
'''function trigger_mode(Type='SFT'):
This function is used to set the trigger mode, Type can be:
- 'SW' or 1 for software controlled trigger
- 'EXT' or 2 for external trigger 1
- further options: edge
- 0 for falling edge
- 1 for rising edge (def)
- 'LVL' or 3 for level trigger mode
- further option: [channel number to use as a trigger,edge,level]
- chn : 1 or 2 (def)
- edge: 0 for falling, 1 for rising (def)
- level: threshold level in digits (def 5958 = 0.2V)