Home | History | Annotate | Download | only in anritsu_lib
      1 #!/usr/bin/env python3.4
      2 #
      3 #   Copyright 2016 - The Android Open Source Project
      4 #
      5 #   Licensed under the Apache License, Version 2.0 (the "License");
      6 #   you may not use this file except in compliance with the License.
      7 #   You may obtain a copy of the License at
      8 #
      9 #       http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 #   Unless required by applicable law or agreed to in writing, software
     12 #   distributed under the License is distributed on an "AS IS" BASIS,
     13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 #   See the License for the specific language governing permissions and
     15 #   limitations under the License.
     16 """
     17 Controller interface for Anritsu Signal Generator MG3710A.
     18 """
     19 
     20 import time
     21 import socket
     22 from enum import Enum
     23 from enum import IntEnum
     24 
     25 from acts.controllers.anritsu_lib._anritsu_utils import AnritsuError
     26 from acts.controllers.anritsu_lib._anritsu_utils import NO_ERROR
     27 from acts.controllers.anritsu_lib._anritsu_utils import OPERATION_COMPLETE
     28 
     29 TERMINATOR = "\n"
     30 
     31 
     32 def create(configs, logger):
     33     objs = []
     34     for c in configs:
     35         ip_address = c["ip_address"]
     36         objs.append(MG3710A(ip_address, logger))
     37     return objs
     38 
     39 
     40 def destroy(objs):
     41     return
     42 
     43 
     44 class MG3710A(object):
     45     """Class to communicate with Anritsu Signal Generator MG3710A.
     46        This uses GPIB command to interface with Anritsu MG3710A """
     47 
     48     def __init__(self, ip_address, log_handle):
     49         self._ipaddr = ip_address
     50         self.log = log_handle
     51 
     52         # Open socket connection to Signaling Tester
     53         self.log.info("Opening Socket Connection with "
     54                       "Signal Generator MG3710A ({}) ".format(self._ipaddr))
     55         try:
     56             self._sock = socket.create_connection(
     57                 (self._ipaddr, 49158), timeout=30)
     58             self.send_query("*IDN?", 60)
     59             self.log.info("Communication Signal Generator MG3710A OK.")
     60             self.log.info("Opened Socket connection to ({})"
     61                           "with handle ({})".format(self._ipaddr, self._sock))
     62         except socket.timeout:
     63             raise AnritsuError("Timeout happened while conencting to"
     64                                " Anritsu MG3710A")
     65         except socket.error:
     66             raise AnritsuError("Socket creation error")
     67 
     68     def disconnect(self):
     69         """ Disconnect Signal Generator MG3710A
     70 
     71         Args:
     72           None
     73 
     74         Returns:
     75             None
     76         """
     77         self.send_command(":SYST:COMM:GTL", opc=False)
     78         self._sock.close()
     79 
     80     def send_query(self, query, sock_timeout=10):
     81         """ Sends a Query message to Anritsu MG3710A and return response
     82 
     83         Args:
     84             query - Query string
     85 
     86         Returns:
     87             query response
     88         """
     89         self.log.info("--> {}".format(query))
     90         querytoSend = (query + TERMINATOR).encode('utf-8')
     91         self._sock.settimeout(sock_timeout)
     92         try:
     93             self._sock.send(querytoSend)
     94             result = self._sock.recv(256).rstrip(TERMINATOR.encode('utf-8'))
     95             response = result.decode('utf-8')
     96             self.log.info('<-- {}'.format(response))
     97             return response
     98         except socket.timeout:
     99             raise AnritsuError("Timeout: Response from Anritsu")
    100         except socket.error:
    101             raise AnritsuError("Socket Error")
    102 
    103     def send_command(self, command, sock_timeout=30, opc=True):
    104         """ Sends a Command message to Anritsu MG3710A
    105 
    106         Args:
    107             command - command string
    108 
    109         Returns:
    110             None
    111         """
    112         self.log.info("--> {}".format(command))
    113         cmdToSend = (command + TERMINATOR).encode('utf-8')
    114         self._sock.settimeout(sock_timeout)
    115         try:
    116             self._sock.send(cmdToSend)
    117             if opc:
    118                 # check operation status
    119                 status = self.send_query("*OPC?")
    120                 if int(status) != OPERATION_COMPLETE:
    121                     raise AnritsuError("Operation not completed")
    122         except socket.timeout:
    123             raise AnritsuError("Timeout for Command Response from Anritsu")
    124         except socket.error:
    125             raise AnritsuError("Socket Error for Anritsu command")
    126         return
    127 
    128     @property
    129     def sg(self):
    130         """ Gets current selected signal generator(SG)
    131 
    132         Args:
    133             None
    134 
    135         Returns:
    136             selected signal generatr number
    137         """
    138         return self.send_query("PORT?")
    139 
    140     @sg.setter
    141     def sg(self, sg_number):
    142         """ Selects the signal generator to be controlled
    143 
    144         Args:
    145             sg_number: sg number 1 | 2
    146 
    147         Returns:
    148             None
    149         """
    150         cmd = "PORT {}".format(sg_number)
    151         self.send_command(cmd)
    152 
    153     def get_modulation_state(self, sg=1):
    154         """ Gets the RF signal modulation state (ON/OFF) of signal generator
    155 
    156         Args:
    157             sg: signal generator number.
    158                 Default is 1
    159 
    160         Returns:
    161             modulation state . 0 (OFF) | 1(ON)
    162         """
    163         return self.send_query("OUTP{}:MOD?".format(sg))
    164 
    165     def set_modulation_state(self, state, sg=1):
    166         """ Sets the RF signal modulation state
    167 
    168         Args:
    169             sg: signal generator number.
    170                 Default is 1
    171             state : ON/OFF
    172 
    173         Returns:
    174             None
    175         """
    176         cmd = "OUTP{}:MOD {}".format(sg, state)
    177         self.send_command(cmd)
    178 
    179     def get_rf_output_state(self, sg=1):
    180         """ Gets RF signal output state (ON/OFF) of signal generator
    181 
    182         Args:
    183             sg: signal generator number.
    184                 Default is 1
    185 
    186         Returns:
    187             RF signal output state . 0 (OFF) | 1(ON)
    188         """
    189         return self.send_query("OUTP{}?".format(sg))
    190 
    191     def set_rf_output_state(self, state, sg=1):
    192         """ Sets the RF signal output state
    193 
    194         Args:
    195             sg: signal generator number.
    196                 Default is 1
    197             state : ON/OFF
    198 
    199         Returns:
    200             None
    201         """
    202         cmd = "OUTP{} {}".format(sg, state)
    203         self.send_command(cmd)
    204 
    205     def get_frequency(self, sg=1):
    206         """ Gets the selected frequency of signal generator
    207 
    208         Args:
    209             sg: signal generator number.
    210                 Default is 1
    211 
    212         Returns:
    213             selected frequency
    214         """
    215         return self.send_query("SOUR{}:FREQ?".format(sg))
    216 
    217     def set_frequency(self, freq, sg=1):
    218         """ Sets the frequency of signal generator
    219 
    220         Args:
    221             sg: signal generator number.
    222                 Default is 1
    223             freq : frequency
    224 
    225         Returns:
    226             None
    227         """
    228         cmd = "SOUR{}:FREQ {}".format(sg, freq)
    229         self.send_command(cmd)
    230 
    231     def get_frequency_offset_state(self, sg=1):
    232         """ Gets the Frequency Offset enable state (ON/OFF) of signal generator
    233 
    234         Args:
    235             sg: signal generator number.
    236                 Default is 1
    237 
    238         Returns:
    239             Frequency Offset enable state . 0 (OFF) | 1(ON)
    240         """
    241         return self.send_query("SOUR{}:FREQ:OFFS:STAT?".format(sg))
    242 
    243     def set_frequency_offset_state(self, state, sg=1):
    244         """ Sets the Frequency Offset enable state
    245 
    246         Args:
    247             sg: signal generator number.
    248                 Default is 1
    249             state : enable state, ON/OFF
    250 
    251         Returns:
    252             None
    253         """
    254         cmd = "SOUR{}:FREQ:OFFS:STAT {}".format(sg, state)
    255         self.send_command(cmd)
    256 
    257     def get_frequency_offset(self, sg=1):
    258         """ Gets the current frequency offset value
    259 
    260         Args:
    261             sg: signal generator number.
    262                 Default is 1
    263 
    264         Returns:
    265             current frequency offset value
    266         """
    267         return self.send_query("SOUR{}:FREQ:OFFS?".format(sg))
    268 
    269     def set_frequency_offset(self, offset, sg=1):
    270         """ Sets the frequency offset value
    271 
    272         Args:
    273             sg: signal generator number.
    274                 Default is 1
    275             offset : frequency offset value
    276 
    277         Returns:
    278             None
    279         """
    280         cmd = "SOUR{}:FREQ:OFFS {}".format(sg, offset)
    281         self.send_command(cmd)
    282 
    283     def get_frequency_offset_multiplier_state(self, sg=1):
    284         """ Gets the Frequency Offset multiplier enable state (ON/OFF) of
    285             signal generator
    286 
    287         Args:
    288             sg: signal generator number.
    289                 Default is 1
    290 
    291         Returns:
    292             Frequency Offset  multiplier enable state . 0 (OFF) | 1(ON)
    293         """
    294         return self.send_query("SOUR{}:FREQ:MULT:STAT?".format(sg))
    295 
    296     def set_frequency_offset_multiplier_state(self, state, sg=1):
    297         """ Sets the  Frequency Offset multiplier enable state
    298 
    299         Args:
    300             sg: signal generator number.
    301                 Default is 1
    302             state : enable state, ON/OFF
    303 
    304         Returns:
    305             None
    306         """
    307         cmd = "SOUR{}:FREQ:MULT:STAT {}".format(sg, state)
    308         self.send_command(cmd)
    309 
    310     def get_frequency_offset_multiplier(self, sg=1):
    311         """ Gets the current frequency offset multiplier value
    312 
    313         Args:
    314             sg: signal generator number.
    315                 Default is 1
    316 
    317         Returns:
    318             frequency offset multiplier value
    319         """
    320         return self.send_query("SOUR{}:FREQ:MULT?".format(sg))
    321 
    322     def set_frequency_offset_multiplier(self, multiplier, sg=1):
    323         """ Sets the frequency offset multiplier value
    324 
    325         Args:
    326             sg: signal generator number.
    327                 Default is 1
    328             multiplier : frequency offset multiplier value
    329 
    330         Returns:
    331             None
    332         """
    333         cmd = "SOUR{}:FREQ:MULT {}".format(sg, multiplier)
    334         self.send_command(cmd)
    335 
    336     def get_channel(self, sg=1):
    337         """ Gets the current channel number
    338 
    339         Args:
    340             sg: signal generator number.
    341                 Default is 1
    342 
    343         Returns:
    344             current channel number
    345         """
    346         return self.send_query("SOUR{}:FREQ:CHAN:NUMB?".format(sg))
    347 
    348     def set_channel(self, channel, sg=1):
    349         """ Sets the channel number
    350 
    351         Args:
    352             sg: signal generator number.
    353                 Default is 1
    354             channel : channel number
    355 
    356         Returns:
    357             None
    358         """
    359         cmd = "SOUR{}:FREQ:CHAN:NUMB {}".format(sg, channel)
    360         self.send_command(cmd)
    361 
    362     def get_channel_group(self, sg=1):
    363         """ Gets the current channel group number
    364 
    365         Args:
    366             sg: signal generator number.
    367                 Default is 1
    368 
    369         Returns:
    370             current channel group number
    371         """
    372         return self.send_query("SOUR{}:FREQ:CHAN:GRO?".format(sg))
    373 
    374     def set_channel_group(self, group, sg=1):
    375         """ Sets the channel group number
    376 
    377         Args:
    378             sg: signal generator number.
    379                 Default is 1
    380             group : channel group number
    381 
    382         Returns:
    383             None
    384         """
    385         cmd = "SOUR{}:FREQ:CHAN:GRO {}".format(sg, group)
    386         self.send_command(cmd)
    387 
    388     def get_rf_output_level(self, sg=1):
    389         """ Gets the current RF output level
    390 
    391         Args:
    392             sg: signal generator number.
    393                 Default is 1
    394 
    395         Returns:
    396             current RF output level
    397         """
    398         return self.send_query("SOUR{}:POW:CURR?".format(sg))
    399 
    400     def get_output_level_unit(self, sg=1):
    401         """ Gets the current RF output level unit
    402 
    403         Args:
    404             sg: signal generator number.
    405                 Default is 1
    406 
    407         Returns:
    408             current RF output level unit
    409         """
    410         return self.send_query("UNIT{}:POW?".format(sg))
    411 
    412     def set_output_level_unit(self, unit, sg=1):
    413         """ Sets the RF output level unit
    414 
    415         Args:
    416             sg: signal generator number.
    417                 Default is 1
    418             unit : Output level unit
    419 
    420         Returns:
    421             None
    422         """
    423         cmd = "UNIT{}:POW {}".format(sg, unit)
    424         self.send_command(cmd)
    425 
    426     def get_output_level(self, sg=1):
    427         """ Gets the Output level
    428 
    429         Args:
    430             sg: signal generator number.
    431                 Default is 1
    432 
    433         Returns:
    434             Output level
    435         """
    436         return self.send_query("SOUR{}:POW?".format(sg))
    437 
    438     def set_output_level(self, level, sg=1):
    439         """ Sets the Output level
    440 
    441         Args:
    442             sg: signal generator number.
    443                 Default is 1
    444             level : Output level
    445 
    446         Returns:
    447             None
    448         """
    449         cmd = "SOUR{}:POW {}".format(sg, level)
    450         self.send_command(cmd)
    451 
    452     def get_arb_state(self, sg=1):
    453         """ Gets the ARB function state
    454 
    455         Args:
    456             sg: signal generator number.
    457                 Default is 1
    458 
    459         Returns:
    460             ARB function state . 0 (OFF) | 1(ON)
    461         """
    462         return self.send_query("SOUR{}:RAD:ARB?".format(sg))
    463 
    464     def set_arb_state(self, state, sg=1):
    465         """ Sets the ARB function state
    466 
    467         Args:
    468             sg: signal generator number.
    469                 Default is 1
    470             state : enable state (ON/OFF)
    471 
    472         Returns:
    473             None
    474         """
    475         cmd = "SOUR{}:RAD:ARB {}".format(sg, state)
    476         self.send_command(cmd)
    477 
    478     def restart_arb_waveform_pattern(self, sg=1):
    479         """ playback the waveform pattern from the beginning.
    480 
    481         Args:
    482             sg: signal generator number.
    483                 Default is 1
    484 
    485         Returns:
    486             None
    487         """
    488         cmd = "SOUR{}:RAD:ARB:WAV:REST".format(sg)
    489         self.send_command(cmd)
    490 
    491     def load_waveform(self, package_name, pattern_name, memory, sg=1):
    492         """ loads the waveform from HDD to specified memory
    493 
    494         Args:
    495             sg: signal generator number.
    496                 Default is 1
    497             package_name : Package name of signal
    498             pattern_name : Pattern name of signal
    499             memory: memory for the signal - "A" or "B"
    500 
    501         Returns:
    502             None
    503         """
    504         cmd = "MMEM{}:LOAD:WAV:WM{} '{}','{}'".format(sg, memory, package_name,
    505                                                       pattern_name)
    506         self.send_command(cmd)
    507 
    508     def select_waveform(self, package_name, pattern_name, memory, sg=1):
    509         """ Selects the waveform to output on specified memory
    510 
    511         Args:
    512             sg: signal generator number.
    513                 Default is 1
    514             package_name : Package name of signal
    515             pattern_name : Pattern name of signal
    516             memory: memory for the signal - "A" or "B"
    517 
    518         Returns:
    519             None
    520         """
    521         cmd = "SOUR{}:RAD:ARB:WM{}:WAV '{}','{}'".format(
    522             sg, memory, package_name, pattern_name)
    523         self.send_command(cmd)
    524 
    525     def get_freq_relative_display_status(self, sg=1):
    526         """ Gets the frequency relative display status
    527 
    528         Args:
    529             sg: signal generator number.
    530                 Default is 1
    531 
    532         Returns:
    533             frequency relative display status.   0 (OFF) | 1(ON)
    534         """
    535         return self.send_query("SOUR{}:FREQ:REF:STAT?".format(sg))
    536 
    537     def set_freq_relative_display_status(self, enable, sg=1):
    538         """ Sets frequency relative display status
    539 
    540         Args:
    541             sg: signal generator number.
    542                 Default is 1
    543             enable : enable type (ON/OFF)
    544 
    545         Returns:
    546             None
    547         """
    548         cmd = "SOUR{}:FREQ:REF:STAT {}".format(sg, enable)
    549         self.send_command(cmd)
    550 
    551     def get_freq_channel_display_type(self, sg=1):
    552         """ Gets the selected type(frequency/channel) for input display
    553 
    554         Args:
    555             sg: signal generator number.
    556                 Default is 1
    557 
    558         Returns:
    559             selected type(frequecy/channel) for input display
    560         """
    561         return self.send_query("SOUR{}:FREQ:TYPE?".format(sg))
    562 
    563     def set_freq_channel_display_type(self, freq_channel, sg=1):
    564         """ Sets thes type(frequency/channel) for input display
    565 
    566         Args:
    567             sg: signal generator number.
    568                 Default is 1
    569             freq_channel : display type (frequency/channel)
    570 
    571         Returns:
    572             None
    573         """
    574         cmd = "SOUR{}:FREQ:TYPE {}".format(sg, freq_channel)
    575         self.send_command(cmd)
    576 
    577     def get_arb_combination_mode(self, sg=1):
    578         """ Gets the current mode to generate the pattern
    579 
    580         Args:
    581             sg: signal generator number.
    582                 Default is 1
    583 
    584         Returns:
    585             current mode to generate the pattern
    586         """
    587         return self.send_query("SOUR{}:RAD:ARB:PCOM?".format(sg))
    588 
    589     def set_arb_combination_mode(self, mode, sg=1):
    590         """ Sets the mode to generate the pattern
    591 
    592         Args:
    593             sg: signal generator number.
    594                 Default is 1
    595             mode : pattern generation mode
    596 
    597         Returns:
    598             None
    599         """
    600         cmd = "SOUR{}:RAD:ARB:PCOM {}".format(sg, mode)
    601         self.send_command(cmd)
    602 
    603     def get_arb_pattern_aorb_state(self, a_or_b, sg=1):
    604         """ Gets the Pattern A/B output state
    605 
    606         Args:
    607             sg: signal generator number.
    608                 Default is 1
    609             a_or_b : Patten A or Pattern B( "A" or "B")
    610 
    611         Returns:
    612             Pattern A/B output state . 0(OFF) | 1(ON)
    613         """
    614         return self.send_query("SOUR{}:RAD:ARB:WM{}:OUTP?".format(a_or_b, sg))
    615 
    616     def set_arb_pattern_aorb_state(self, a_or_b, state, sg=1):
    617         """ Sets the Pattern A/B output state
    618 
    619         Args:
    620             sg: signal generator number.
    621                 Default is 1
    622             a_or_b : Patten A or Pattern B( "A" or "B")
    623             state : output state
    624 
    625         Returns:
    626             None
    627         """
    628         cmd = "SOUR{}:RAD:ARB:WM{}:OUTP {}".format(sg, a_or_b, state)
    629         self.send_command(cmd)
    630 
    631     def get_arb_level_aorb(self, a_or_b, sg=1):
    632         """ Gets the Pattern A/B output level
    633 
    634         Args:
    635             sg: signal generator number.
    636                 Default is 1
    637             a_or_b : Patten A or Pattern B( "A" or "B")
    638 
    639         Returns:
    640              Pattern A/B output level
    641         """
    642         return self.send_query("SOUR{}:RAD:ARB:WM{}:POW?".format(sg, a_or_b))
    643 
    644     def set_arb_level_aorb(self, a_or_b, level, sg=1):
    645         """ Sets the Pattern A/B output level
    646 
    647         Args:
    648             sg: signal generator number.
    649                 Default is 1
    650             a_or_b : Patten A or Pattern B( "A" or "B")
    651             level : output level
    652 
    653         Returns:
    654             None
    655         """
    656         cmd = "SOUR{}:RAD:ARB:WM{}:POW {}".format(sg, a_or_b, level)
    657         self.send_command(cmd)
    658 
    659     def get_arb_freq_offset(self, sg=1):
    660         """ Gets the frequency offset between Pattern A and Patten B
    661             when CenterSignal is A or B.
    662 
    663         Args:
    664             sg: signal generator number.
    665                 Default is 1
    666 
    667         Returns:
    668             frequency offset between Pattern A and Patten B
    669         """
    670         return self.send_query("SOUR{}:RAD:ARB:FREQ:OFFS?".format(sg))
    671 
    672     def set_arb_freq_offset(self, offset, sg=1):
    673         """ Sets the frequency offset between Pattern A and Patten B when
    674             CenterSignal is A or B.
    675 
    676         Args:
    677             sg: signal generator number.
    678                 Default is 1
    679             offset : frequency offset
    680 
    681         Returns:
    682             None
    683         """
    684         cmd = "SOUR{}:RAD:ARB:FREQ:OFFS {}".format(sg, offset)
    685         self.send_command(cmd)
    686 
    687     def get_arb_freq_offset_aorb(self, sg=1):
    688         """ Gets the frequency offset of Pattern A/Pattern B based on Baseband
    689             center frequency
    690 
    691         Args:
    692             sg: signal generator number.
    693                 Default is 1
    694 
    695         Returns:
    696             frequency offset
    697         """
    698         return self.send_query(
    699             "SOUR{}:RAD:ARB:WM{}:FREQ:OFFS?".format(sg, a_or_b))
    700 
    701     def set_arb_freq_offset_aorb(self, a_or_b, offset, sg=1):
    702         """ Sets the frequency offset of Pattern A/Pattern B based on Baseband
    703             center frequency
    704 
    705         Args:
    706             sg: signal generator number.
    707                 Default is 1
    708             a_or_b : Patten A or Pattern B( "A" or "B")
    709             offset : frequency offset
    710 
    711         Returns:
    712             None
    713         """
    714         cmd = "SOUR{}:RAD:ARB:WM{}:FREQ:OFFS {}".format(sg, a_or_b, offset)
    715         self.send_command(cmd)
    716