Ejemplo n.º 1
0
class Driver(BaseDriver):
    support_models = [
        'M3202A',
    ]

    quants = [
        QReal('Amplitude', value=1, unit='V', ch=0),
        #DC WaveShape
        QReal('Offset', value=0, unit='V', ch=0),
        #Function Generators(FGs) mode
        QReal('Frequency', unit='Hz', ch=0),
        QReal('Phase', value=0, unit='deg', ch=0),
        QOption('WaveShape',
                ch=0,
                value='HIZ',
                options=[('HIZ', -1), ('NoSignal', 0), ('Sin', 1),
                         ('Triangular', 2), ('Square', 4), ('DC', 5),
                         ('AWG', 6), ('PartnerCH', 8)]),
        #clock
        QReal('clockFrequency', unit='Hz'),
        QReal('clockSyncFrequency', unit='Hz'),
        # 板卡向外输出的时钟,默认状态关闭
        QOption('clockIO', value='OFF', options=[('OFF', 0), ('ON', 1)]),
        QOption('triggerIO',
                value='SyncIN',
                options=[('noSyncOUT', (0, 0)), ('SyncOUT', (0, 1)),
                         ('noSyncIN', (1, 0)), ('SyncIN', (1, 1))]),
        QOption('triggerMode',
                value='ExternalCycle',
                ch=0,
                options=[('Auto', 0), ('SWtri', 1), ('SWtriCycle', 5),
                         ('External', 2), ('ExternalCycle', 6)]),
        QOption('triExtSource',
                value='EXTERN',
                ch=0,
                options=[('EXTERN', 0), ('PXI0', 4000), ('PXI1', 4001),
                         ('PXI2', 4002), ('PXI3', 4003), ('PXI4', 4004),
                         ('PXI5', 4005), ('PXI6', 4006), ('PXI7', 4007)]),
        QOption('triggerBehavior',
                value='RISE',
                ch=0,
                options=[('NONE', 0), ('HIGH', 1), ('LOW', 2), ('RISE', 3),
                         ('FALL', 4)]),
        # Defines the delay between the trigger and the waveform launch in tens of ns
        QInteger(
            'startDelay',
            value=0,
            unit='ns',
            ch=0,
        ),
        # Number of times the waveform is repeated once launched (negative means infinite)
        QInteger(
            'cycles',
            value=0,
            ch=0,
        ),
        # Waveform prescaler value, to reduce the effective sampling rate
        QInteger(
            'prescaler',
            value=0,
            ch=0,
        ),
        QOption('Output',
                ch=0,
                value='Close',
                options=[('Stop', 0), ('Run', 1), ('Pause', 2), ('Resume', 3),
                         ('Close', -1)]),
        QList('WList', value=[]),
        QList('SList', value=[], ch=0),
    ]
    #CHs : 仪器通道
    # CHs=[0,1,2,3]
    CHs = [1, 2, 3, 4]

    # config : 用来存储参数配置,防止由于多通道引起的混乱
    config = {}

    def __init__(self, **kw):
        BaseDriver.__init__(self, **kw)
        self.chassis = kw['CHASSIS']
        self.slot = kw['SLOT']

    def newcfg(self):
        self.config = {}
        for q in self.quants:
            _cfg = {q.name: {}}
            if q.ch is not None:
                for i in self.CHs:
                    _cfg[q.name].update(
                        {i: {
                            'value': q.value,
                            'unit': q.unit
                        }})
            else:
                _cfg[q.name].update({0: {'value': q.value, 'unit': q.unit}})
            self.config.update(_cfg)
        log.info('new config!')

    def loadcfg(self, file=None):
        if file == None:
            file = self.caches_file
        with open(file, 'r', encoding='utf-8') as f:
            self.config = yaml.load(f)
        log.info('load config: %s', file)

    def savecfg(self, file=None):
        if file == None:
            file = self.caches_file
        with open(file, 'w', encoding='utf-8') as f:
            yaml.dump(self.config, f)
        log.info('save config: %s', file)

    def performOpen(self):
        #SD_AOU module
        self.AWG = inspur_sd.SD_AOU()
        self.model = self.AWG.getProductNameBySlot(self.chassis, self.slot)
        moduleID = self.AWG.openWithSlot(self.model, self.chassis, self.slot)
        if moduleID < 0:
            print("Module open error:", moduleID)
        self.caches_file = caches_dir() / (self.model + '_config_caches.yaml')
        try:
            self.loadcfg()
        except Exception:
            log.exception(Exception)
            self.newcfg()
            self.savecfg()

    def performClose(self):
        """Perform the close instrument connection operation"""
        # refer labber driver keysight_pxi_awg.py
        # do not check for error if close was called with an error
        try:
            #             print('0')
            #             print('3')
            #             print('13')
            self.setValue('clockIO', 'OFF')
            #             print('2')
            # clear old waveforms and stop awg
            self.waveformFlush()
            #             print('4')
            for ch in self.CHs:
                #                 print('5')
                self.closeCh(ch)
            # close instrument
            # self.AWG.close()
#             print('6')
            self.savecfg()
#             print('7')
        except Exception:
            #             print('1')
            # never return error here
            pass

    def closeCh(self, ch=0):
        #         print('8')
        self.AWG.AWGstop(ch)
        #         print('9')
        self.AWG.AWGflush(ch)
        #         print('10')
        self.config['SList'][ch]['value'] = []
        #         print('11')
        self.AWG.channelWaveShape(ch, -1)
        #         print('12')
        self.config['WaveShape'][ch]['value'] = 'HIZ'
        self.config['Output'][ch]['value'] = 'Close'

    def performSetValue(self, quant, value, ch=0, **kw):
        _cfg = {}
        if quant.name == 'Amplitude':
            self.AWG.channelAmplitude(ch, value)
        elif quant.name == 'Offset':
            self.AWG.channelOffset(ch, value)
        elif quant.name == 'Frequency':
            self.AWG.channelFrequency(ch, value)
        elif quant.name == 'Phase':
            self.phaseReset(ch)
            self.AWG.channelPhase(ch, value)
        elif quant.name == 'WaveShape':
            options = dict(quant.options)
            self.AWG.channelWaveShape(ch, options[value])
        elif quant.name == 'clockFrequency':
            mode = kw.get('mode', 1)
            self.AWG.clockSetFrequency(value, mode)
            ch = 0
        elif quant.name == 'clockIO':
            options = dict(quant.options)
            self.AWG.clockIOconfig(options[value])
            ch = 0
        elif quant.name == 'triggerIO':
            options = dict(quant.options)
            self.AWG.triggerIOconfigV5(*options[value])
            ch = 0
        elif quant.name == 'Output':
            if value == 'Stop':
                self.AWG.AWGstop(ch)
            elif value == 'Run':
                self.AWG.AWGstart(ch)
            elif value == 'Pause':
                self.AWG.AWGpause(ch)
            elif value == 'Resume':
                self.AWG.AWGresume(ch)
            elif value == 'Close':
                self.closeCh(ch)
        elif quant.name == 'clockSyncFrequency':
            print("clockSyncFrequency can't be set")
            return
        _cfg['value'] = value
        self.config[quant.name][ch].update(_cfg)

    def performGetValue(self, quant, ch=0, **kw):
        _cfg = {}
        if quant.name == 'clockFrequency':
            value = self.AWG.clockGetFrequency()
            ch = 0
            _cfg['value'] = value
        elif quant.name == 'clockSyncFrequency':
            value = self.AWG.clockGetSyncFrequency()
            ch = 0
            _cfg['value'] = value
        elif quant.name in ['clockIO', 'triggerIO']:
            ch = 0
        self.config[quant.name][ch].update(_cfg)
        return self.config[quant.name][ch]['value']

    def phaseReset(self, ch=0):
        self.AWG.channelPhaseReset(ch)
        _cfg = {'value': 0}
        self.config['Phase'][ch].update(_cfg)

    def clockResetPhase(self):
        # self.AWG.clockResetPhase(triggerBehavior, triggerSource, skew = 0.0)
        pass

    def newWaveform(self, file_arrayA, arrayB=None, waveformType=0):
        '''Memory usage: Waveforms created with New are stored in the PC RAM,
        not in the module onboard RAM. Therefore, the limitation in the number
        of waveforms and their sizes is given by the amount of PC RAM.'''
        # waveformType 0: Analog 16Bits, Analog normalized waveforms (-1..1) defined with doubles
        # please refer AWG Waveform types about others
        wave = inspur_sd.SD_Wave()
        if isinstance(file_arrayA, str):
            wave.newFromFile(file_arrayA)
            return wave
        else:
            # 5: DigitalType, Digital waveforms defined with integers
            if waveformType == 5:
                wave.newFromArrayInteger(waveformType, file_arrayA, arrayB)
            else:
                wave.newFromArrayDouble(waveformType, file_arrayA, arrayB)
            return wave

    def waveformLoad(self, waveform, num, paddingMode=0):
        '''num: waveform_num, 在板上内存的波形编号'''
        if num in self.config['WList'][0]['value']:
            self.AWG.waveformReLoad(waveform, num, paddingMode)
        else:
            # This function replaces a waveform located in the module onboard RAM.
            # The size of the newwaveform must be smaller than or equal to the existing waveform.
            self.AWG.waveformLoad(waveform, num, paddingMode)
            self.config['WList'][0]['value'].append(num)

    # def waveformReLoad(self, waveform, num, paddingMode = 0):
    #     '''This function replaces a waveform located in the module onboard RAM.
    #     The size of the newwaveform must be smaller than or equal to the existing waveform.'''
    #     self.AWG.waveformReLoad(waveform, num, paddingMode)

    def waveformFlush(self):
        '''This function deletes all the waveforms from the module onboard RAM
        and flushes all the AWG queues'''
        #         print('14')
        self.AWG.waveformFlush()
        #         print('15')
        self.config['WList'][0]['value'] = []
#         print('16')
#         self.config['SList'][0]['value']=[]
#         print('17')

    def AWGflush(self, ch=0):
        '''This function empties the queue of the selected Arbitrary Waveform Generator,
        Waveforms are not removed from the module onboard RAM.'''
        self.AWG.AWGflush(ch)
        self.config['SList'][0]['value'] = []

    def _getParams(self, ch):
        triggerModeIndex = self.getValue('triggerMode', ch=ch)
        triggerModeOptions = self.quantities['triggerMode'].options
        triggerMode = dict(triggerModeOptions)[triggerModeIndex]

        if triggerModeIndex in ['External', 'ExternalCycle']:

            triExtSourceIndex = self.getValue('triExtSource', ch=ch)
            triExtSourceOptions = self.quantities['triExtSource'].options
            triExtSource = dict(triExtSourceOptions)[triExtSourceIndex]
            if triExtSourceIndex in ['EXTERN']:
                # 若未设置过,则从config读取默认配置;若已设置,则结果不变
                triggerIO = self.getValue('triggerIO')
                self.setValue('triggerIO', triggerIO)

            triggerBehaviorIndex = self.getValue('triggerBehavior', ch=ch)
            triggerBehaviorOptions = self.quantities['triggerBehavior'].options
            triggerBehavior = dict(
                triggerBehaviorOptions)[triggerBehaviorIndex]

            self.AWG.AWGtriggerExternalConfig(ch, triExtSource,
                                              triggerBehavior)

        startDelay = self.getValue('startDelay', ch=ch)
        cycles = self.getValue('cycles', ch=ch)
        prescaler = self.getValue('prescaler', ch=ch)

        return triggerMode, startDelay, cycles, prescaler

    def AWGqueueWaveform(self, ch=0, waveform_num=0):
        self.setValue('WaveShape', 'AWG', ch=ch)
        Amplitude = self.getValue('Amplitude', ch=ch)
        self.setValue('Amplitude', Amplitude, ch=ch)

        triggerMode, startDelay, cycles, prescaler = self._getParams(ch)

        self.AWG.AWGqueueWaveform(ch, waveform_num, triggerMode, startDelay,
                                  cycles, prescaler)
        self.config['SList'][ch]['value'].append(waveform_num)

    def AWGrun(self,
               file_arrayA,
               arrayB=None,
               ch=0,
               waveformType=0,
               paddingMode=0):
        '''从文件或序列快速产生波形'''
        print('0')
        self.setValue('WaveShape', 'AWG', ch=ch)
        print('1')
        Amplitude = self.getValue('Amplitude', ch=ch)
        print('2')
        self.setValue('Amplitude', Amplitude, ch=ch)
        print('3')

        triggerMode, startDelay, cycles, prescaler = self._getParams(ch)
        print('4')

        if isinstance(file_arrayA, str):
            # AWGFromFile 有bug
            self.AWG.AWGFromFile(ch, file_arrayA, triggerMode, startDelay,
                                 cycles, prescaler, paddingMode)
        else:
            print('5')
            self.AWG.AWGfromArray(ch, triggerMode, startDelay, cycles,
                                  prescaler, waveformType, file_arrayA, arrayB,
                                  paddingMode)
            print('6')
        self.config['Output'][ch]['value'] = 'Run'
        print('7')
Ejemplo n.º 2
0
class Driver(BaseDriver):
    support_models = ['AWG70001A', 'AWG70002A']

    quants = [
        # Sample Rate set_cmd is block cmd
        #
        QReal('Sample Rate',
              unit='S/s',
              set_cmd='CLOC:SRAT %(value).10e; *WAI;',
              get_cmd='CLOC:SRAT?'),
        QOption('Run Mode',
                value='CONT',
                ch=1,
                set_cmd='SOUR%(ch)d:RMOD %(option)s',
                get_cmd='SOUR%(ch)d:RMOD?',
                options=[('Continuous', 'CONT'), ('Triggered', 'TRIG'),
                         ('TContinuous', 'TCON')]),
        QOption('Clock Source',
                value='INT',
                set_cmd='CLOC:SOUR %(option)s',
                get_cmd='CLOC:SOUR?',
                options=[('Internal', 'INT'), ('External', 'EXT'),
                         ('Efixed', 'EFIX'), ('Evariable', 'EVAR')]),

        # QOption('Reference Source', set_cmd='SOUR:ROSC:SOUR %(option)s', get_cmd='SOUR:ROSC:SOUR?',
        #   options = [('Internal', 'INT'), ('External', 'EXT')]),
        QReal('Multiplier Rate ',
              value=1,
              set_cmd='CLOC:EREF:MULT %(value)d',
              get_cmd='CLOC:EREF:MULT?'),
        QReal('Divider Rate ',
              value=1,
              set_cmd='CLOC:EREF:DIV %(value)d',
              get_cmd='CLOC:EREF:DIV?'),

        # 以下四种只在 output path 为 Direct 时有效
        # Vpp range: 250-500mVpp
        QReal('Vpp',
              unit='Vpp',
              ch=1,
              set_cmd='SOUR%(ch)d:VOLT %(value)f%(unit)s',
              get_cmd='SOUR%(ch)d:VOLT?'),
        QReal('Offset',
              unit='V',
              ch=1,
              set_cmd='SOUR%(ch)d:VOLT:OFFS %(value)f%(unit)s',
              get_cmd='SOUR%(ch)d:VOLT:OFFS?'),
        QReal('Volt Low',
              unit='V',
              ch=1,
              set_cmd='SOUR%(ch)d:VOLT:LOW %(value)f%(unit)s',
              get_cmd='SOUR%(ch)d:VOLT:LOW?'),
        QReal('Volt High',
              unit='V',
              ch=1,
              set_cmd='SOUR%(ch)d:VOLT:HIGH %(value)f%(unit)s',
              get_cmd='SOUR%(ch)d:VOLT:HIGH?'),

        # output delay in time
        QReal('timeDelay',
              unit='s',
              ch=1,
              set_cmd='SOUR%(ch)d:DEL:ADJ %(value)f%(unit)s',
              get_cmd='SOUR%(ch)d:DEL:ADJ?'),
        # output delay in point
        QReal('timeDelay',
              unit='point',
              ch=1,
              set_cmd='SOUR%(ch)d:DEL:POIN %(value)d',
              get_cmd='SOUR%(ch)d:DELy:POIN?'),
        QOption('Run',
                value='Play',
                set_cmd='AWGC:%(option)s; *WAI;',
                get_cmd='AWGC:RST?',
                options=[('Play', 'RUN'), ('Stop', 'STOP')]),
        QOption('Output',
                ch=1,
                set_cmd='OUTP%(ch)d %(option)s',
                get_cmd='OUTP%(ch)d?',
                options=[('ON', 1), ('OFF', 0), (1, 'ON'), (0, 'OFF')]),
        QList('WList'),
        QList('SList'),

        # INSTrument MODE : AWG or FG
        QOption('instMode',
                value='AWG',
                set_cmd='INST:MODE %(option)s',
                get_cmd='INST:MODE?',
                options=[
                    ('AWG', 'AWG'),
                    ('FG', 'FGEN'),
                ]),
        QOption('FG Type',
                ch=1,
                value='Sin',
                set_cmd='FGEN:CHAN%(ch)d:TYPE %(option)s',
                get_cmd='FGEN:CHAN%(ch)d:TYPE?',
                options=[
                    ('Sin', 'SINE'),
                    ('Square', 'SQU'),
                    ('Triangle', 'TRI'),
                    ('Noise', 'NOIS'),
                    ('DC', 'DC'),
                    ('Gaussian', 'GAUS'),
                    ('ExpRise', 'EXPR'),
                    ('ExpDecay', 'EXPD'),
                    ('None', 'NONE'),
                ]),
        QReal('FG Amplitude',
              ch=1,
              value=0.5,
              unit='V',
              set_cmd='FGEN:CHAN%(ch)d:AMPL:VOLT %(value)f%(unit)s',
              get_cmd='FGEN:CHAN%(ch)d:AMPL:VOLT?'),

        #FG Offset -150mV~150mV, min Unit 1mV
        QReal('FG Offset',
              ch=1,
              value=0,
              unit='V',
              set_cmd='FGEN:CHAN%(ch)d:OFFS %(value)f%(unit)s',
              get_cmd='FGEN:CHAN%(ch)d:OFFS?'),
        QReal('FG Phase',
              ch=1,
              value=0,
              unit='deg',
              set_cmd='FGEN:CHAN%(ch)d:PHAS %(value)f',
              get_cmd='FGEN:CHAN%(ch)d:PHAS?'),
        QReal('FG Frequency',
              ch=1,
              value=1e6,
              unit='Hz',
              set_cmd='FGEN:CHAN%(ch)d:FREQ %(value)f%(unit)s',
              get_cmd='FGEN:CHAN%(ch)d:FREQ?'),
        QReal(
            'FG Period',
            ch=1,
            unit='s',
            # 周期与频率绑定,无法设置周期,但可读
            set_cmd='',
            get_cmd='FGEN:CHAN%(ch)d:PER?'),

        # DC Level Range: –250 mV to 250 mV
        QReal('FG DC',
              ch=1,
              value=0,
              unit='V',
              set_cmd='FGEN:CHAN%(ch)d:DCL %(value)f%(unit)s',
              get_cmd='FGEN:CHAN%(ch)d:DCL?'),
        QReal('FG High',
              ch=1,
              value=0.25,
              unit='V',
              set_cmd='FGEN:CHAN%(ch)d:HIGH %(value)f%(unit)s',
              get_cmd='FGEN:CHAN%(ch)d:HIGH?'),
        QReal('FG Low',
              ch=1,
              value=-0.25,
              unit='V',
              set_cmd='FGEN:CHAN%(ch)d:LOW %(value)f%(unit)s',
              get_cmd='FGEN:CHAN%(ch)d:LOW?'),

        #coupling mode: DIR, DCAM, AC
        QOption('FG Path',
                ch=1,
                value='Direct',
                set_cmd='FGEN:CHAN%(ch)d:PATH %(option)s',
                get_cmd='FGEN:CHAN%(ch)d:PATH?',
                options=[
                    ('Direct', 'DIR'),
                    ('DCAmplified', 'DCAM'),
                    ('AC', 'AC'),
                ]),
    ]

    def performOpen(self):
        self.waveform_list = self.get_waveform_list()
        try:  #没有sequence模块的仪器会产生一个错误
            self.sequence_list = self.get_sequence_list()
        except:
            self.sequence_list = None

    def performSetValue(self, quant, value, **kw):
        if quant.name == '':
            return
        else:
            return BaseDriver.performSetValue(self, quant, value, **kw)

    def performGetValue(self, quant, **kw):
        if quant.name == 'WList':
            self.waveform_list = self.get_waveform_list()
            return self.waveform_list
        elif quant.name == 'SList':
            self.sequence_list = self.get_sequence_list()
            return self.sequence_list
        else:
            return BaseDriver.performGetValue(self, quant, **kw)

    def get_waveform_list(self):
        return self.query('WLIS:LIST?').strip("\"\n' ").split(',')

    def get_sequence_list(self):
        ret = []
        slist_size = int(self.query("SLIS:SIZE?"))
        for i in range(slist_size):
            ret.append(self.query("SLIS:NAME? %d" % i).strip("\"\n '"))
        return ret

    def create_waveform(self, name, length, format='REAL'):
        '''format: REAL or IQ'''
        if name in self.waveform_list:
            return
        self.write('WLIS:WAV:NEW "%s",%d,%s;*WAI;' % (name, length, format))
        self.waveform_list = self.get_waveform_list()

    def remove_waveform(self, name=None, all=False):
        if all:
            self.write('WLIS:WAV:DEL ALL; *WAI;')
            self.waveform_list.clear()
        elif name not in self.waveform_list:
            return
        else:
            self.write('WLIS:WAV:DEL "%s"; *WAI;' % name)
            self.waveform_list = self.get_waveform_list()

    def get_waveform_length(self, name):
        size = int(self.query('WLIS:WAV:LENGTH? "%s"' % name))
        return size

    def use_waveform(self, name, ch=1, type=None):
        '''type: I or Q'''
        if type is not None:
            self.write('SOUR%d:CASS:WAV "%s",%s' % (ch, name, type))
        else:
            self.write('SOUR%d:CASS:WAV "%s"' % (ch, name))
        self.write('*WAI;')

    # 关于RUN的设置和状态询问,建议使用Quantity:Run的方法
    def run_state(self):
        return int(self.query('AWGC:RST?'))

    def run(self):
        self.write('AWGC:RUN')
        self.write('*WAI')

    def stop(self):
        self.write('AWGC:STOP')

    # 关于Output的设置和状态询问,建议使用Quantity:Output的方法
    def output_on(self, ch=1):
        self.write('OUTP%d:STAT 1' % ch)

    def output_off(self, ch=1):
        self.write('OUTP%d:STAT 0' % ch)

    def get_current_asset(self, ch=1):
        current_type = self.query('SOUR%d:CASS:TYPE?' % ch)
        current_asset = self.query('SOUR%d:CASS?' % ch)
        return current_type, current_asset

    def update_waveform(self, points, name='ABS', IQ='I', start=0, size=None):
        w_type = self.query('WLIS:WAV:TYPE? "%s"' % name).strip()
        if w_type == 'REAL':
            self._update_waveform_float(points, name, IQ, start, size)
        elif w_type == 'IQ':
            self._update_waveform_float(points[0], name, 'I', start, size)
            self._update_waveform_float(points[1], name, 'Q', start, size)
        self.write('*WAI;')
        # else:
        #     self._update_waveform_int(points, name, start, size)

    # def _update_waveform_int(self, points, name='ABS', start=0, size=None):
    #     """
    #     points : a 1D numpy.array which values between -1 and 1.
    #     """
    #     message = 'WLIST:WAVEFORM:DATA "%s",%d,' % (name, start)
    #     if size is not None:
    #         message = message + ('%d,' % size)
    #     points = points.clip(-1,1)
    #     values = (points * 0x1fff).astype(int) + 0x1fff
    #     self.write_binary_values(message, values, datatype=u'H',
    #                              is_big_endian=False,
    #                              termination=None, encoding=None)

    def _update_waveform_float(self,
                               points,
                               name='ABS',
                               IQ='I',
                               start=0,
                               size=None):
        message = 'WLIST:WAVEFORM:DATA:%s "%s",%d,' % (IQ, name, start)
        if size is not None:
            message = message + ('%d,' % size)
        values = points.clip(-1, 1)
        self.write_binary_values(message,
                                 values,
                                 datatype=u'f',
                                 is_big_endian=False,
                                 termination=None,
                                 encoding=None)

    # def update_marker(self, name, mk1, mk2=None, mk3=None, mk4=None, start=0, size=None):
    #     def format_marker_data(markers, bits):
    #         values = 0
    #         for i, v in markers:
    #             v = 0 if v is None else np.asarray(v)
    #             values += v << bits[i]
    #         return values
    #
    #     if self.model in ['AWG5014C']:
    #         values = format_marker_data([mk1, mk2], [5,6])
    #     elif self.model in ['AWG5208']:
    #         values = format_marker_data([mk1, mk2, mk3, mk4], [7,6,5,4])
    #     if size is None:
    #         message = 'WLIST:WAVEFORM:MARKER:DATA "%s",%d,' % (name, start)
    #     else:
    #         message = 'WLIST:WAVEFORM:MARKER:DATA "%s",%d,%d,' % (name, start, size)
    #     self.write_binary_values(message, values, datatype=u'B',
    #                              is_big_endian=False,
    #                              termination=None, encoding=None)

    def create_sequence(self, name, steps, tracks=1):
        if name in self.sequence_list:
            return
        self.write('SLIS:SEQ:NEW "%s", %d, %d; *WAI;' % (name, steps, tracks))
        self.sequence_list = self.get_sequence_list()

    def remove_sequence(self, name=None, all=False):
        if all:
            self.write('SLIS:SEQ:DEL ALL; *WAI;')
            self.sequence_list.clear()
        elif name not in self.sequence_list:
            return
        else:
            self.write('SLIS:SEQ:DEL "%s"; *WAI;' % name)
            self.sequence_list = self.get_sequence_list()

    #
    # def set_sequence_step(self, name, sub_name, step, wait='OFF', goto='NEXT', repeat=1, jump=None):
    #     """set a step of sequence
    #
    #     name: sequence name
    #     sub_name: subsequence name or list of waveforms for every tracks
    #     wait: ATRigger | BTRigger | ITRigger | OFF
    #     goto: <NR1> | LAST | FIRSt | NEXT | END
    #     repeat: ONCE | INFinite | <NR1>
    #     jump: a tuple (jump_input, jump_to)
    #         jump_input: ATRigger | BTRigger | OFF | ITRigger
    #         jump_to: <NR1> | NEXT | FIRSt | LAST | END
    #     """
    #     if isinstance(sub_name, str):
    #         self.write('SLIS:SEQ:STEP%d:TASS:SEQ "%s","%s"' % (step, name, sub_name))
    #     else:
    #         for i, wav in enumerate(sub_name):
    #             self.write('SLIS:SEQ:STEP%d:TASS%d:WAV "%s","%s"' % (step, i+1, name, wav))
    #     self.write('SLIS:SEQ:STEP%d:WINP "%s", %s' % (step, name, wait))
    #     self.write('SLIS:SEQ:STEP%d:GOTO "%s", %s' % (step, name, goto))
    #     self.write('SLIS:SEQ:STEP%d:RCO "%s", %s' % (step, name, repeat))
    #     if jump is not None:
    #         self.write('SLIS:SEQ:STEP%d:EJIN "%s", %s' % (step, name, jump[0]))
    #         self.write('SLIS:SEQ:STEP%d:EJUM "%s", %s' % (step, name, jump[1]))

    def use_sequence(self, name, ch=1, track=1, type=None):
        '''type: I or Q'''
        if type is not None:
            self.write('SOUR%d:CASS:SEQ "%s", %d, %s' %
                       (ch, name, track, type))
        else:
            self.write('SOUR%d:CASS:SEQ "%s", %d' % (ch, name, track))
        self.write('*WAI;')
Ejemplo n.º 3
0
class Driver(BaseDriver):
    support_models = ['AWG5014C', 'AWG5208']

    quants = [
        QReal('Sample Rate',
              unit='S/s',
              set_cmd='SOUR:FREQ %(value)f',
              get_cmd='SOUR:FREQ?'),
        QOption('Run Mode',
                set_cmd='AWGC:RMOD %(option)s',
                get_cmd='AWGC:RMOD?',
                options=[('Continuous', 'CONT'), ('Triggered', 'TRIG'),
                         ('Gated', 'GAT'), ('Sequence', 'SEQ')]),
        QOption('Clock Source',
                set_cmd='AWGC:CLOC:SOUR %(option)s',
                get_cmd='AWGC:CLOC:SOUR?',
                options=[('Internal', 'INT'), ('External', 'EXT')]),
        QOption('Reference Source',
                set_cmd='SOUR:ROSC:SOUR %(option)s',
                get_cmd='SOUR:ROSC:SOUR?',
                options=[('Internal', 'INT'), ('External', 'EXT')]),
        QReal('Vpp',
              unit='V',
              ch=1,
              set_cmd='SOUR%(ch)d:VOLT %(value)f',
              get_cmd='SOUR%(ch)d:VOLT?'),
        QReal('Offset',
              unit='V',
              ch=1,
              set_cmd='SOUR%(ch)d:VOLT:OFFS %(value)f',
              get_cmd='SOUR%(ch)d:VOLT:OFFS?'),
        QReal('Volt Low',
              unit='V',
              ch=1,
              set_cmd='SOUR%(ch)d:VOLT:LOW %(value)f',
              get_cmd='SOUR%(ch)d:VOLT:LOW?'),
        QReal('Volt High',
              unit='V',
              ch=1,
              set_cmd='SOUR%(ch)d:VOLT:HIGH %(value)f',
              get_cmd='SOUR%(ch)d:VOLT:HIGH?'),
        QReal('Force Jump',
              unit='Step',
              ch=1,
              set_cmd=' SOURCE%(ch)d:JUMP:FORCE %(value)f'),
        # output delay in time
        QReal('timeDelay',
              unit='s',
              ch=1,
              set_cmd='SOUR%(ch)d:DEL:ADJ %(value)f%(unit)s',
              get_cmd='SOUR%(ch)d:DEL:ADJ?'),
        # output delay in point
        QReal('pointDelay',
              unit='point',
              ch=1,
              set_cmd='SOUR%(ch)d:DEL:POIN %(value)d',
              get_cmd='SOUR%(ch)d:DEL:POIN?'),
        QList('WList'),
        QList('SList'),
    ]

    def performOpen(self):
        self.waveform_list = self.get_waveform_list()
        try:  #没有sequence模块的仪器会产生一个错误
            self.sequence_list = self.get_sequence_list()
        except:
            self.sequence_list = None

    def performSetValue(self, quant, value, **kw):
        if quant.name == '':
            return
        else:
            return BaseDriver.performSetValue(self, quant, value, **kw)

    def performGetValue(self, quant, **kw):
        if quant.name == 'WList':
            quant.value = self.waveform_list
            return self.waveform_list
        elif quant.name == 'SList':
            quant.value = self.sequence_list
            return self.sequence_list
        else:
            return BaseDriver.performGetValue(self, quant, **kw)

    def get_waveform_list(self):
        if self.model in ['AWG5208']:
            return self.query('WLIS:LIST?').strip("\"\n' ").split(',')
        elif self.model in ['AWG5014C']:
            ret = []
            wlist_size = int(self.query("WLIS:SIZE?"))
            for i in range(wlist_size):
                ret.append(self.query("WLIS:NAME? %d" % i).strip("\"\n '"))
            return ret
        else:
            return []

    def get_sequence_list(self):
        if self.model in ['AWG5208']:
            ret = []
            slist_size = int(self.query("SLIS:SIZE?"))
            for i in range(slist_size):
                ret.append(
                    self.query("SLIS:NAME? %d" % (i + 1)).strip("\"\n '"))
            return ret
        else:
            return []

    def create_waveform(self, name, length, format=None):
        '''
        format: REAL, INT or IQ
        '''
        if name in self.waveform_list:
            return
        if format is None:
            if self.model in ['AWG5208']:
                format = 'REAL'
            else:
                format = 'INT'
        self.write('WLIS:WAV:NEW "%s",%d,%s;' % (name, length, format))
        self.waveform_list.append(name)

    def remove_waveform(self, name):
        if name not in self.waveform_list:
            return
        self.waveform_list.remove(name)
        self.write(':WLIS:WAV:DEL "%s"; *CLS' % name)

    def clear_waveform_list(self):
        wavs_to_delete = self.waveform_list.copy()
        for name in wavs_to_delete:
            self.remove_waveform(name)

    def use_waveform(self, name, ch=1):
        self.write('SOURCE%d:WAVEFORM "%s"' % (ch, name))

    def run_state(self):
        return int(self.query('AWGC:RST?'))

    def run(self):
        self.write('AWGC:RUN')
        self.write('*WAI')

    def stop(self):
        self.write('AWGC:STOP')

    def output_on(self, ch=1):
        self.write('OUTP%d:STAT 1' % ch)

    def output_off(self, ch=1):
        self.write('OUTP%d:STAT 0' % ch)

    def get_current_waveforms(self):
        current_waveforms = []
        current_waveform_size = 0
        for i in [1, 2, 3, 4]:
            wn = self.query('SOUR%d:WAV?' % i)[1:-2]
            current_waveforms.append(wn)
            if wn != '' and current_waveform_size == 0:
                current_waveform_size = self.query_ascii_values(
                    'WLIS:WAV:LENGTH? "%s"' % wn, 'd')[0]
        return current_waveform_size, current_waveforms

    def update_waveform(self, points, name='ABS', IQ='I', start=0, size=None):
        w_type = self.query('WLISt:WAVeform:TYPE? "%s"' % name).strip()
        if w_type == 'REAL':
            self._update_waveform_float(points, name, IQ, start, size)
        elif w_type == 'IQ':
            self._update_waveform_float(points[0], name, 'I', start, size)
            self._update_waveform_float(points[1], name, 'Q', start, size)
        else:
            self._update_waveform_int(points, name, start, size)

    def _update_waveform_int(self, points, name='ABS', start=0, size=None):
        """
        points : a 1D numpy.array which values between -1 and 1.
        """
        message = 'WLIST:WAVEFORM:DATA "%s",%d,' % (name, start)
        if size is not None:
            message = message + ('%d,' % size)
        points = points.clip(-1, 1)
        values = (points * 0x1fff).astype(int) + 0x1fff
        self.write_binary_values(message,
                                 values,
                                 datatype=u'H',
                                 is_big_endian=False,
                                 termination=None,
                                 encoding=None)
        self.query('*OPC?')

    def _update_waveform_float(self,
                               points,
                               name='ABS',
                               IQ='I',
                               start=0,
                               size=None):
        if self.model == 'AWG5208':
            message = 'WLIST:WAVEFORM:DATA:%s "%s",%d,' % (IQ, name, start)
        else:
            message = 'WLIST:WAVEFORM:DATA "%s",%d,' % (name, start)
        if size is not None:
            message = message + ('%d,' % size)
        values = points.clip(-1, 1)
        self.write_binary_values(message,
                                 values,
                                 datatype=u'f',
                                 is_big_endian=False,
                                 termination=None,
                                 encoding=None)
        self.query('*OPC?')

    def update_marker(self,
                      name,
                      mk1=None,
                      mk2=None,
                      mk3=None,
                      mk4=None,
                      start=0,
                      size=None):
        def format_marker_data(markers, bits):
            values = 0
            for i, v in enumerate(markers):
                v = 0 if v is None else np.asarray(v, dtype=int)
                values += v << bits[i]
            return values

        if self.model in ['AWG5014C']:
            values = format_marker_data([mk1, mk2], [6, 7])
        elif self.model in ['AWG5208']:
            values = format_marker_data([mk1, mk2, mk3, mk4], [7, 6, 5, 4])
        if size is None:
            message = 'WLIST:WAVEFORM:MARKER:DATA "%s",%d,' % (name, start)
        else:
            message = 'WLIST:WAVEFORM:MARKER:DATA "%s",%d,%d,' % (name, start,
                                                                  size)
        self.write_binary_values(message,
                                 values,
                                 datatype=u'B',
                                 is_big_endian=False,
                                 termination=None,
                                 encoding=None)
        self.query('*OPC?')

    def create_sequence(self, name, steps, tracks):
        if name in self.sequence_list:
            return
        self.write('SLIS:SEQ:NEW "%s", %d, %d' % (name, steps, tracks))
        self.sequence_list.append(name)

    def remove_sequence(self, name):
        if name not in self.sequence_list:
            return
        self.sequence_list.remove(name)
        self.write('SLIS:SEQ:DEL "%s"' % name)

    def clear_sequence_list(self):
        self.write('SLIS:SEQ:DEL ALL')
        self.sequence_list.clear()

    def set_sequence_step(self,
                          name,
                          sub_name,
                          step,
                          wait='OFF',
                          goto='NEXT',
                          repeat=1,
                          jump=None):
        """set a step of sequence
        name: sequence name
        sub_name: subsequence name or list of waveforms for every tracks
        wait: ATRigger | BTRigger | ITRigger | OFF
        goto: <NR1> | LAST | FIRSt | NEXT | END
        repeat: ONCE | INFinite | <NR1>
        jump: a tuple (jump_input, jump_to)
            jump_input: ATRigger | BTRigger | OFF | ITRigger
            jump_to: <NR1> | NEXT | FIRSt | LAST | END
        """
        if isinstance(sub_name, str):
            self.write('SLIS:SEQ:STEP%d:TASS:SEQ "%s","%s"' %
                       (step, name, sub_name))
        else:
            for i, wav in enumerate(sub_name):
                self.write('SLIS:SEQ:STEP%d:TASS%d:WAV "%s","%s"' %
                           (step, i + 1, name, wav))
        self.write('SLIS:SEQ:STEP%d:WINP "%s", %s' % (step, name, wait))
        self.write('SLIS:SEQ:STEP%d:GOTO "%s", %s' % (step, name, goto))
        self.write('SLIS:SEQ:STEP%d:RCO "%s", %s' % (step, name, repeat))
        if jump is not None:
            self.write('SLIS:SEQ:STEP%d:EJIN "%s", %s' % (step, name, jump[0]))
            self.write('SLIS:SEQ:STEP%d:EJUM "%s", %s' % (step, name, jump[1]))

    def set_seq(self,
                wave_name,
                step,
                track,
                seq_name=None,
                tag=None,
                wait='ATR',
                goto='NEXT',
                repeat='1',
                eventinput='OFF',
                eventjump='NEXT'):
        """set a step of sequence
        seq_name: sequence name
        wave_name: subsequence name or list of waveforms for every tracks
        wait: ATRigger | BTRigger | ITRigger | OFF
        goto: <NR1> | LAST | FIRSt | NEXT | END
        repeat: ONCE | INFinite | <NR1>
        eventinput: 
            jump_input: ATRigger | BTRigger | OFF | ITRigger
        eventjump:
            jump_to: <NR1> | NEXT | FIRSt | LAST | END
        """
        if tag == 'subseq':
            self.write('SLISt:SEQ:STEP%d:TASSet%d:SEQ "%s","%s"' %
                       (step, track, seq_name, wave_name))
        else:
            for i, wav in enumerate(wave_name, start=2):
                step = i
                if i == 2:
                    self.write('SLIS:SEQ:STEP%d:TASS%d:WAV "%s","%s"' %
                               (1, track, seq_name, wav))
                    self.write('SLIS:SEQ:STEP%d:WINP "%s", %s' %
                               (1, seq_name, 'BTR'))
                    self.write('SLIS:SEQ:STEP%d:GOTO "%s", %s' %
                               (1, seq_name, goto))
                    self.write('SLIS:SEQ:STEP%d:RCO "%s", %s' %
                               (1, seq_name, repeat))
                    self.write('SLIS:SEQ:STEP%d:EJIN "%s", %s' %
                               (1, seq_name, eventinput))
                    self.write('SLIS:SEQ:STEP%d:EJUM "%s", %s' %
                               (1, seq_name, eventjump))

                self.write('SLIS:SEQ:STEP%d:TASS%d:WAV "%s","%s"' %
                           (step, track, seq_name, wav))
                self.write('SLIS:SEQ:STEP%d:WINP "%s", %s' %
                           (step, seq_name, wait))
                self.write('SLIS:SEQ:STEP%d:GOTO "%s", %s' %
                           (step, seq_name, goto))
                self.write('SLIS:SEQ:STEP%d:RCO "%s", %s' %
                           (step, seq_name, repeat))
                self.write('SLIS:SEQ:STEP%d:EJIN "%s", %s' %
                           (step, seq_name, eventinput))
                self.write('SLIS:SEQ:STEP%d:EJUM "%s", %s' %
                           (step, seq_name, eventjump))

                if i == len(wave_name) + 1:
                    if len(wave_name) % 64 != 0:
                        num = (len(wave_name) // 64 +
                               1) * 64 - len(wave_name) + 5
                    else:
                        num = 5
                    self.write('SLIS:SEQ:STEP%d:RCO "%s", %s' %
                               (step, seq_name, num))
                    self.write('SLIS:SEQ:STEP%d:GOTO "%s", %s' %
                               (step, seq_name, 'FIRST'))

    def use_sequence(self, name, channels=[1, 2]):
        for i, ch in enumerate(channels):
            self.write('SOUR%d:CASS:SEQ "%s", %d' % (ch, name, i + 1))
            self.write('*WAI')
Ejemplo n.º 4
0
class Driver(BaseDriver):
    support_models = ['AWG70001A', 'AWG70002A']

    quants = [
        QReal('Sample Rate',
              unit='S/s',
              set_cmd='CLOC:SRAT %(value).10e',
              get_cmd='CLOC:SRAT?'),
        QOption('Run Mode',
                value='CONT',
                ch=1,
                set_cmd='SOUR%(ch)d:RMOD %(option)s',
                get_cmd='SOUR%(ch)d:RMOD?',
                options=[('Continuous', 'CONT'), ('Triggered', 'TRIG'),
                         ('TContinuous', 'TCON')]),
        QOption('Clock Source',
                value='INT',
                set_cmd='CLOC:SOUR %(option)s',
                get_cmd='CLOC:SOUR?',
                options=[('Internal', 'INT'), ('External', 'EXT'),
                         ('Efixed', 'EFIX'), ('Evariable', 'EVAR')]),

        # QOption('Reference Source', set_cmd='SOUR:ROSC:SOUR %(option)s', get_cmd='SOUR:ROSC:SOUR?',
        #   options = [('Internal', 'INT'), ('External', 'EXT')]),
        QReal('Multiplier Rate ',
              value=1,
              set_cmd='CLOC:EREF:MULT %(value)d',
              get_cmd='CLOC:EREF:MULT?'),
        QReal('Divider Rate ',
              value=1,
              set_cmd='CLOC:EREF:DIV %(value)d',
              get_cmd='CLOC:EREF:DIV?'),
        QReal('Amplitude',
              unit='V',
              ch=1,
              set_cmd='SOUR%(ch)d:VOLT %(value)f%(unit)s',
              get_cmd='SOUR%(ch)d:VOLT?'),
        QReal('Offset',
              unit='V',
              ch=1,
              set_cmd='SOUR%(ch)d:VOLT:OFFS %(value)f%(unit)s',
              get_cmd='SOUR%(ch)d:VOLT:OFFS?'),
        QReal('Volt Low',
              unit='V',
              ch=1,
              set_cmd='SOUR%(ch)d:VOLT:LOW %(value)f%(unit)s',
              get_cmd='SOUR%(ch)d:VOLT:LOW?'),
        QReal('Volt High',
              unit='V',
              ch=1,
              set_cmd='SOUR%(ch)d:VOLT:HIGH %(value)f%(unit)s',
              get_cmd='SOUR%(ch)d:VOLT:HIGH?'),
        # output delay in time
        QReal('timeDelay',
              unit='s',
              ch=1,
              set_cmd='SOUR%(ch)d:DEL:ADJ %(value)f%(unit)s',
              get_cmd='SOUR%(ch)d:DEL:ADJ?'),
        # output delay in point
        QReal('timeDelay',
              unit='point',
              ch=1,
              set_cmd='SOUR%(ch)d:DEL:POIN %(value)d',
              get_cmd='SOUR%(ch)d:DELy:POIN?'),
        QOption('Output',
                ch=1,
                set_cmd='OUTP%(ch)d %(option)d',
                get_cmd='OUTP%(ch)d?',
                options=[('ON', 1), ('OFF', 0), (1, 1), (0, 0)]),
        QList('WList'),
        QList('SList'),
    ]

    def performOpen(self):
        self.waveform_list = self.get_waveform_list()
        try:  #没有sequence模块的仪器会产生一个错误
            self.sequence_list = self.get_sequence_list()
        except:
            self.sequence_list = None

    def performSetValue(self, quant, value, **kw):
        if quant.name == '':
            return
        else:
            return BaseDriver.performSetValue(self, quant, value, **kw)

    def performGetValue(self, quant, **kw):
        if quant.name == 'WList':
            self.waveform_list = self.get_waveform_list()
            return self.waveform_list
        elif quant.name == 'SList':
            self.sequence_list = self.get_sequence_list()
            return self.sequence_list
        else:
            return BaseDriver.performGetValue(self, quant, **kw)

    def get_waveform_list(self):
        return self.query('WLIS:LIST?').strip("\"\n' ").split(',')

    def get_sequence_list(self):
        ret = []
        slist_size = int(self.query("SLIS:SIZE?"))
        for i in range(slist_size):
            ret.append(self.query("SLIS:NAME? %d" % i).strip("\"\n '"))
        return ret

    def create_waveform(self, name, length, format='REAL'):
        '''format: REAL or IQ'''
        if name in self.waveform_list:
            return
        self.write('WLIS:WAV:NEW "%s",%d,%s;' % (name, length, format))
        self.waveform_list = self.get_waveform_list()

    def remove_waveform(self, name=None, all=False):
        if all:
            self.write('WLIS:WAV:DEL ALL; *CLS')
            self.waveform_list.clear()
        elif name not in self.waveform_list:
            return
        else:
            self.write('WLIS:WAV:DEL "%s"; *CLS' % name)
            self.waveform_list = self.get_waveform_list()

    def use_waveform(self, name, ch=1, type=None):
        '''type: I or Q'''
        if type is not None:
            self.write('SOUR%d:CASS:WAV "%s",%s' % (ch, name, type))
        else:
            self.write('SOUR%d:CASS:WAV "%s"' % (ch, name))

    def run_state(self):
        return int(self.query('AWGC:RST?'))

    def run(self):
        self.write('AWGC:RUN')
        self.write('*WAI')

    def stop(self):
        self.write('AWGC:STOP')

    def get_current_asset(self, ch=1):
        current_type = self.query('SOUR%d:CASS:TYPE?' % ch)
        current_asset = self.query('SOUR%d:CASS?' % ch)
        return current_type, current_asset

    def update_waveform(self, points, name='ABS', IQ='I', start=0, size=None):
        w_type = self.query('WLISt:WAV:TYPE? "%s"' % name).strip()
        if w_type == 'REAL':
            self._update_waveform_float(points, name, IQ, start, size)
        elif w_type == 'IQ':
            self._update_waveform_float(points[0], name, 'I', start, size)
            self._update_waveform_float(points[1], name, 'Q', start, size)
        # else:
        #     self._update_waveform_int(points, name, start, size)

    # def _update_waveform_int(self, points, name='ABS', start=0, size=None):
    #     """
    #     points : a 1D numpy.array which values between -1 and 1.
    #     """
    #     message = 'WLIST:WAVEFORM:DATA "%s",%d,' % (name, start)
    #     if size is not None:
    #         message = message + ('%d,' % size)
    #     points = points.clip(-1,1)
    #     values = (points * 0x1fff).astype(int) + 0x1fff
    #     self.write_binary_values(message, values, datatype=u'H',
    #                              is_big_endian=False,
    #                              termination=None, encoding=None)

    def _update_waveform_float(self,
                               points,
                               name='ABS',
                               IQ='I',
                               start=0,
                               size=None):
        message = 'WLIST:WAVEFORM:DATA:%s "%s",%d,' % (IQ, name, start)
        if size is not None:
            message = message + ('%d,' % size)
        values = points.clip(-1, 1)
        self.write_binary_values(message,
                                 values,
                                 datatype=u'f',
                                 is_big_endian=False,
                                 termination=None,
                                 encoding=None)

    # def update_marker(self, name, mk1, mk2=None, mk3=None, mk4=None, start=0, size=None):
    #     def format_marker_data(markers, bits):
    #         values = 0
    #         for i, v in markers:
    #             v = 0 if v is None else np.asarray(v)
    #             values += v << bits[i]
    #         return values
    #
    #     if self.model in ['AWG5014C']:
    #         values = format_marker_data([mk1, mk2], [5,6])
    #     elif self.model in ['AWG5208']:
    #         values = format_marker_data([mk1, mk2, mk3, mk4], [7,6,5,4])
    #     if size is None:
    #         message = 'WLIST:WAVEFORM:MARKER:DATA "%s",%d,' % (name, start)
    #     else:
    #         message = 'WLIST:WAVEFORM:MARKER:DATA "%s",%d,%d,' % (name, start, size)
    #     self.write_binary_values(message, values, datatype=u'B',
    #                              is_big_endian=False,
    #                              termination=None, encoding=None)

    def create_sequence(self, name, steps, tracks=1):
        if name in self.sequence_list:
            return
        self.write('SLIS:SEQ:NEW "%s", %d, %d' % (name, steps, tracks))
        self.sequence_list = self.get_sequence_list()

    def remove_sequence(self, name=None, all=False):
        if all:
            self.write('SLIS:SEQ:DEL ALL; *CLS')
            self.sequence_list.clear()
        elif name not in self.sequence_list:
            return
        else:
            self.write('SLIS:SEQ:DEL "%s"' % name)
            self.sequence_list = self.get_sequence_list()

    #
    # def set_sequence_step(self, name, sub_name, step, wait='OFF', goto='NEXT', repeat=1, jump=None):
    #     """set a step of sequence
    #
    #     name: sequence name
    #     sub_name: subsequence name or list of waveforms for every tracks
    #     wait: ATRigger | BTRigger | ITRigger | OFF
    #     goto: <NR1> | LAST | FIRSt | NEXT | END
    #     repeat: ONCE | INFinite | <NR1>
    #     jump: a tuple (jump_input, jump_to)
    #         jump_input: ATRigger | BTRigger | OFF | ITRigger
    #         jump_to: <NR1> | NEXT | FIRSt | LAST | END
    #     """
    #     if isinstance(sub_name, str):
    #         self.write('SLIS:SEQ:STEP%d:TASS:SEQ "%s","%s"' % (step, name, sub_name))
    #     else:
    #         for i, wav in enumerate(sub_name):
    #             self.write('SLIS:SEQ:STEP%d:TASS%d:WAV "%s","%s"' % (step, i+1, name, wav))
    #     self.write('SLIS:SEQ:STEP%d:WINP "%s", %s' % (step, name, wait))
    #     self.write('SLIS:SEQ:STEP%d:GOTO "%s", %s' % (step, name, goto))
    #     self.write('SLIS:SEQ:STEP%d:RCO "%s", %s' % (step, name, repeat))
    #     if jump is not None:
    #         self.write('SLIS:SEQ:STEP%d:EJIN "%s", %s' % (step, name, jump[0]))
    #         self.write('SLIS:SEQ:STEP%d:EJUM "%s", %s' % (step, name, jump[1]))

    def use_sequence(self, name, ch=1, track=1, type=None):
        '''type: I or Q'''
        if type is not None:
            self.write('SOUR%d:CASS:SEQ "%s", %d, %s' %
                       (ch, name, track, type))
        else:
            self.write('SOUR%d:CASS:SEQ "%s", %d' % (ch, name, track))