blob: a9df65d713d5c922e990fcc72a13f325da0a29a2 [file] [log] [blame]
#!/usr/bin/env python3
#
# Copyright 2016 - The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Controller interface for Anritsu Signal Generator MG3710A.
"""
import logging
import time
import socket
from enum import Enum
from enum import IntEnum
from acts.controllers.anritsu_lib._anritsu_utils import AnritsuError
from acts.controllers.anritsu_lib._anritsu_utils import NO_ERROR
from acts.controllers.anritsu_lib._anritsu_utils import OPERATION_COMPLETE
from acts import tracelogger
TERMINATOR = "\n"
def create(configs):
objs = []
for c in configs:
ip_address = c["ip_address"]
objs.append(MG3710A(ip_address))
return objs
def destroy(objs):
return
class MG3710A(object):
"""Class to communicate with Anritsu Signal Generator MG3710A.
This uses GPIB command to interface with Anritsu MG3710A """
def __init__(self, ip_address):
self._ipaddr = ip_address
self.log = tracelogger.TraceLogger(logging.getLogger())
# Open socket connection to Signaling Tester
self.log.info("Opening Socket Connection with "
"Signal Generator MG3710A ({}) ".format(self._ipaddr))
try:
self._sock = socket.create_connection(
(self._ipaddr, 49158), timeout=30)
self.send_query("*IDN?", 60)
self.log.info("Communication Signal Generator MG3710A OK.")
self.log.info("Opened Socket connection to ({})"
"with handle ({})".format(self._ipaddr, self._sock))
except socket.timeout:
raise AnritsuError("Timeout happened while conencting to"
" Anritsu MG3710A")
except socket.error:
raise AnritsuError("Socket creation error")
def disconnect(self):
""" Disconnect Signal Generator MG3710A
Args:
None
Returns:
None
"""
self.send_command(":SYST:COMM:GTL", opc=False)
self._sock.close()
def send_query(self, query, sock_timeout=10):
""" Sends a Query message to Anritsu MG3710A and return response
Args:
query - Query string
Returns:
query response
"""
self.log.info("--> {}".format(query))
querytoSend = (query + TERMINATOR).encode('utf-8')
self._sock.settimeout(sock_timeout)
try:
self._sock.send(querytoSend)
result = self._sock.recv(256).rstrip(TERMINATOR.encode('utf-8'))
response = result.decode('utf-8')
self.log.info('<-- {}'.format(response))
return response
except socket.timeout:
raise AnritsuError("Timeout: Response from Anritsu")
except socket.error:
raise AnritsuError("Socket Error")
def send_command(self, command, sock_timeout=30, opc=True):
""" Sends a Command message to Anritsu MG3710A
Args:
command - command string
Returns:
None
"""
self.log.info("--> {}".format(command))
cmdToSend = (command + TERMINATOR).encode('utf-8')
self._sock.settimeout(sock_timeout)
try:
self._sock.send(cmdToSend)
if opc:
# check operation status
status = self.send_query("*OPC?")
if int(status) != OPERATION_COMPLETE:
raise AnritsuError("Operation not completed")
except socket.timeout:
raise AnritsuError("Timeout for Command Response from Anritsu")
except socket.error:
raise AnritsuError("Socket Error for Anritsu command")
return
@property
def sg(self):
""" Gets current selected signal generator(SG)
Args:
None
Returns:
selected signal generatr number
"""
return self.send_query("PORT?")
@sg.setter
def sg(self, sg_number):
""" Selects the signal generator to be controlled
Args:
sg_number: sg number 1 | 2
Returns:
None
"""
cmd = "PORT {}".format(sg_number)
self.send_command(cmd)
def get_modulation_state(self, sg=1):
""" Gets the RF signal modulation state (ON/OFF) of signal generator
Args:
sg: signal generator number.
Default is 1
Returns:
modulation state . 0 (OFF) | 1(ON)
"""
return self.send_query("OUTP{}:MOD?".format(sg))
def set_modulation_state(self, state, sg=1):
""" Sets the RF signal modulation state
Args:
sg: signal generator number.
Default is 1
state : ON/OFF
Returns:
None
"""
cmd = "OUTP{}:MOD {}".format(sg, state)
self.send_command(cmd)
def get_rf_output_state(self, sg=1):
""" Gets RF signal output state (ON/OFF) of signal generator
Args:
sg: signal generator number.
Default is 1
Returns:
RF signal output state . 0 (OFF) | 1(ON)
"""
return self.send_query("OUTP{}?".format(sg))
def set_rf_output_state(self, state, sg=1):
""" Sets the RF signal output state
Args:
sg: signal generator number.
Default is 1
state : ON/OFF
Returns:
None
"""
cmd = "OUTP{} {}".format(sg, state)
self.send_command(cmd)
def get_frequency(self, sg=1):
""" Gets the selected frequency of signal generator
Args:
sg: signal generator number.
Default is 1
Returns:
selected frequency
"""
return self.send_query("SOUR{}:FREQ?".format(sg))
def set_frequency(self, freq, sg=1):
""" Sets the frequency of signal generator
Args:
sg: signal generator number.
Default is 1
freq : frequency
Returns:
None
"""
cmd = "SOUR{}:FREQ {}".format(sg, freq)
self.send_command(cmd)
def get_frequency_offset_state(self, sg=1):
""" Gets the Frequency Offset enable state (ON/OFF) of signal generator
Args:
sg: signal generator number.
Default is 1
Returns:
Frequency Offset enable state . 0 (OFF) | 1(ON)
"""
return self.send_query("SOUR{}:FREQ:OFFS:STAT?".format(sg))
def set_frequency_offset_state(self, state, sg=1):
""" Sets the Frequency Offset enable state
Args:
sg: signal generator number.
Default is 1
state : enable state, ON/OFF
Returns:
None
"""
cmd = "SOUR{}:FREQ:OFFS:STAT {}".format(sg, state)
self.send_command(cmd)
def get_frequency_offset(self, sg=1):
""" Gets the current frequency offset value
Args:
sg: signal generator number.
Default is 1
Returns:
current frequency offset value
"""
return self.send_query("SOUR{}:FREQ:OFFS?".format(sg))
def set_frequency_offset(self, offset, sg=1):
""" Sets the frequency offset value
Args:
sg: signal generator number.
Default is 1
offset : frequency offset value
Returns:
None
"""
cmd = "SOUR{}:FREQ:OFFS {}".format(sg, offset)
self.send_command(cmd)
def get_frequency_offset_multiplier_state(self, sg=1):
""" Gets the Frequency Offset multiplier enable state (ON/OFF) of
signal generator
Args:
sg: signal generator number.
Default is 1
Returns:
Frequency Offset multiplier enable state . 0 (OFF) | 1(ON)
"""
return self.send_query("SOUR{}:FREQ:MULT:STAT?".format(sg))
def set_frequency_offset_multiplier_state(self, state, sg=1):
""" Sets the Frequency Offset multiplier enable state
Args:
sg: signal generator number.
Default is 1
state : enable state, ON/OFF
Returns:
None
"""
cmd = "SOUR{}:FREQ:MULT:STAT {}".format(sg, state)
self.send_command(cmd)
def get_frequency_offset_multiplier(self, sg=1):
""" Gets the current frequency offset multiplier value
Args:
sg: signal generator number.
Default is 1
Returns:
frequency offset multiplier value
"""
return self.send_query("SOUR{}:FREQ:MULT?".format(sg))
def set_frequency_offset_multiplier(self, multiplier, sg=1):
""" Sets the frequency offset multiplier value
Args:
sg: signal generator number.
Default is 1
multiplier : frequency offset multiplier value
Returns:
None
"""
cmd = "SOUR{}:FREQ:MULT {}".format(sg, multiplier)
self.send_command(cmd)
def get_channel(self, sg=1):
""" Gets the current channel number
Args:
sg: signal generator number.
Default is 1
Returns:
current channel number
"""
return self.send_query("SOUR{}:FREQ:CHAN:NUMB?".format(sg))
def set_channel(self, channel, sg=1):
""" Sets the channel number
Args:
sg: signal generator number.
Default is 1
channel : channel number
Returns:
None
"""
cmd = "SOUR{}:FREQ:CHAN:NUMB {}".format(sg, channel)
self.send_command(cmd)
def get_channel_group(self, sg=1):
""" Gets the current channel group number
Args:
sg: signal generator number.
Default is 1
Returns:
current channel group number
"""
return self.send_query("SOUR{}:FREQ:CHAN:GRO?".format(sg))
def set_channel_group(self, group, sg=1):
""" Sets the channel group number
Args:
sg: signal generator number.
Default is 1
group : channel group number
Returns:
None
"""
cmd = "SOUR{}:FREQ:CHAN:GRO {}".format(sg, group)
self.send_command(cmd)
def get_rf_output_level(self, sg=1):
""" Gets the current RF output level
Args:
sg: signal generator number.
Default is 1
Returns:
current RF output level
"""
return self.send_query("SOUR{}:POW:CURR?".format(sg))
def get_output_level_unit(self, sg=1):
""" Gets the current RF output level unit
Args:
sg: signal generator number.
Default is 1
Returns:
current RF output level unit
"""
return self.send_query("UNIT{}:POW?".format(sg))
def set_output_level_unit(self, unit, sg=1):
""" Sets the RF output level unit
Args:
sg: signal generator number.
Default is 1
unit : Output level unit
Returns:
None
"""
cmd = "UNIT{}:POW {}".format(sg, unit)
self.send_command(cmd)
def get_output_level(self, sg=1):
""" Gets the Output level
Args:
sg: signal generator number.
Default is 1
Returns:
Output level
"""
return self.send_query("SOUR{}:POW?".format(sg))
def set_output_level(self, level, sg=1):
""" Sets the Output level
Args:
sg: signal generator number.
Default is 1
level : Output level
Returns:
None
"""
cmd = "SOUR{}:POW {}".format(sg, level)
self.send_command(cmd)
def get_arb_state(self, sg=1):
""" Gets the ARB function state
Args:
sg: signal generator number.
Default is 1
Returns:
ARB function state . 0 (OFF) | 1(ON)
"""
return self.send_query("SOUR{}:RAD:ARB?".format(sg))
def set_arb_state(self, state, sg=1):
""" Sets the ARB function state
Args:
sg: signal generator number.
Default is 1
state : enable state (ON/OFF)
Returns:
None
"""
cmd = "SOUR{}:RAD:ARB {}".format(sg, state)
self.send_command(cmd)
def restart_arb_waveform_pattern(self, sg=1):
""" playback the waveform pattern from the beginning.
Args:
sg: signal generator number.
Default is 1
Returns:
None
"""
cmd = "SOUR{}:RAD:ARB:WAV:REST".format(sg)
self.send_command(cmd)
def load_waveform(self, package_name, pattern_name, memory, sg=1):
""" loads the waveform from HDD to specified memory
Args:
sg: signal generator number.
Default is 1
package_name : Package name of signal
pattern_name : Pattern name of signal
memory: memory for the signal - "A" or "B"
Returns:
None
"""
cmd = "MMEM{}:LOAD:WAV:WM{} '{}','{}'".format(sg, memory, package_name,
pattern_name)
self.send_command(cmd)
def select_waveform(self, package_name, pattern_name, memory, sg=1):
""" Selects the waveform to output on specified memory
Args:
sg: signal generator number.
Default is 1
package_name : Package name of signal
pattern_name : Pattern name of signal
memory: memory for the signal - "A" or "B"
Returns:
None
"""
cmd = "SOUR{}:RAD:ARB:WM{}:WAV '{}','{}'".format(
sg, memory, package_name, pattern_name)
self.send_command(cmd)
def get_freq_relative_display_status(self, sg=1):
""" Gets the frequency relative display status
Args:
sg: signal generator number.
Default is 1
Returns:
frequency relative display status. 0 (OFF) | 1(ON)
"""
return self.send_query("SOUR{}:FREQ:REF:STAT?".format(sg))
def set_freq_relative_display_status(self, enable, sg=1):
""" Sets frequency relative display status
Args:
sg: signal generator number.
Default is 1
enable : enable type (ON/OFF)
Returns:
None
"""
cmd = "SOUR{}:FREQ:REF:STAT {}".format(sg, enable)
self.send_command(cmd)
def get_freq_channel_display_type(self, sg=1):
""" Gets the selected type(frequency/channel) for input display
Args:
sg: signal generator number.
Default is 1
Returns:
selected type(frequecy/channel) for input display
"""
return self.send_query("SOUR{}:FREQ:TYPE?".format(sg))
def set_freq_channel_display_type(self, freq_channel, sg=1):
""" Sets thes type(frequency/channel) for input display
Args:
sg: signal generator number.
Default is 1
freq_channel : display type (frequency/channel)
Returns:
None
"""
cmd = "SOUR{}:FREQ:TYPE {}".format(sg, freq_channel)
self.send_command(cmd)
def get_arb_combination_mode(self, sg=1):
""" Gets the current mode to generate the pattern
Args:
sg: signal generator number.
Default is 1
Returns:
current mode to generate the pattern
"""
return self.send_query("SOUR{}:RAD:ARB:PCOM?".format(sg))
def set_arb_combination_mode(self, mode, sg=1):
""" Sets the mode to generate the pattern
Args:
sg: signal generator number.
Default is 1
mode : pattern generation mode
Returns:
None
"""
cmd = "SOUR{}:RAD:ARB:PCOM {}".format(sg, mode)
self.send_command(cmd)
def get_arb_pattern_aorb_state(self, a_or_b, sg=1):
""" Gets the Pattern A/B output state
Args:
sg: signal generator number.
Default is 1
a_or_b : Patten A or Pattern B( "A" or "B")
Returns:
Pattern A/B output state . 0(OFF) | 1(ON)
"""
return self.send_query("SOUR{}:RAD:ARB:WM{}:OUTP?".format(a_or_b, sg))
def set_arb_pattern_aorb_state(self, a_or_b, state, sg=1):
""" Sets the Pattern A/B output state
Args:
sg: signal generator number.
Default is 1
a_or_b : Patten A or Pattern B( "A" or "B")
state : output state
Returns:
None
"""
cmd = "SOUR{}:RAD:ARB:WM{}:OUTP {}".format(sg, a_or_b, state)
self.send_command(cmd)
def get_arb_level_aorb(self, a_or_b, sg=1):
""" Gets the Pattern A/B output level
Args:
sg: signal generator number.
Default is 1
a_or_b : Patten A or Pattern B( "A" or "B")
Returns:
Pattern A/B output level
"""
return self.send_query("SOUR{}:RAD:ARB:WM{}:POW?".format(sg, a_or_b))
def set_arb_level_aorb(self, a_or_b, level, sg=1):
""" Sets the Pattern A/B output level
Args:
sg: signal generator number.
Default is 1
a_or_b : Patten A or Pattern B( "A" or "B")
level : output level
Returns:
None
"""
cmd = "SOUR{}:RAD:ARB:WM{}:POW {}".format(sg, a_or_b, level)
self.send_command(cmd)
def get_arb_freq_offset(self, sg=1):
""" Gets the frequency offset between Pattern A and Patten B
when CenterSignal is A or B.
Args:
sg: signal generator number.
Default is 1
Returns:
frequency offset between Pattern A and Patten B
"""
return self.send_query("SOUR{}:RAD:ARB:FREQ:OFFS?".format(sg))
def set_arb_freq_offset(self, offset, sg=1):
""" Sets the frequency offset between Pattern A and Patten B when
CenterSignal is A or B.
Args:
sg: signal generator number.
Default is 1
offset : frequency offset
Returns:
None
"""
cmd = "SOUR{}:RAD:ARB:FREQ:OFFS {}".format(sg, offset)
self.send_command(cmd)
def get_arb_freq_offset_aorb(self, sg=1):
""" Gets the frequency offset of Pattern A/Pattern B based on Baseband
center frequency
Args:
sg: signal generator number.
Default is 1
Returns:
frequency offset
"""
return self.send_query(
"SOUR{}:RAD:ARB:WM{}:FREQ:OFFS?".format(sg, a_or_b))
def set_arb_freq_offset_aorb(self, a_or_b, offset, sg=1):
""" Sets the frequency offset of Pattern A/Pattern B based on Baseband
center frequency
Args:
sg: signal generator number.
Default is 1
a_or_b : Patten A or Pattern B( "A" or "B")
offset : frequency offset
Returns:
None
"""
cmd = "SOUR{}:RAD:ARB:WM{}:FREQ:OFFS {}".format(sg, a_or_b, offset)
self.send_command(cmd)