| import argparse |
| import pexpect |
| import time |
| |
| import common |
| from autotest_lib.client.cros.rf import agilent_scpi |
| |
| class Labtool8797(object): |
| """Labtool commands to control Marvell 8797.""" |
| |
| |
| def __init__(self, labtool_dir): |
| self.labtool8797 = pexpect.spawn(labtool_dir+'/labtool') |
| self.labtool8797.expect('Enter option:') |
| |
| |
| def enter_option(self, option_string, expected_string): |
| """Wrapper of pexpect for labtool. |
| |
| This is a wrapper for the following: |
| 1) Send option_string to self.labtool8797. |
| 2) Wait expected_string, and 'Enter option:' |
| 3) Return the intermediate output from labtool. |
| |
| @param option_string: option string that labtool would process. |
| @param expected_string: the specific pattern to wait from labtool. |
| @return the string in between the expected string and 'Enter option:' |
| """ |
| self.labtool8797.sendline(option_string) |
| self.labtool8797.expect(expected_string) |
| self.labtool8797.expect('Enter option:') |
| return self.labtool8797.before |
| |
| |
| def enter_wifi_menu(self): |
| returned_string = self.enter_option('1', 'W87xx') |
| print 'Entering: W8797' + returned_string |
| |
| |
| def set_path(self, path): |
| """Setting and verifying the TxRx Path. |
| |
| @param path: Tx and Rx path. 1 means antenna 1, 2 means antenna 2, |
| 3 means both antennas are on. |
| """ |
| self.enter_option('10 %d' % path, '0x0') |
| returned_string = self.enter_option('9', 'GetTxRxPath :') |
| print 'Setting TX RX Path:' + returned_string |
| |
| |
| def set_band(self, band): |
| """Setting and verifying the band. |
| |
| @param band: frequency band. 0 means 2.4 GHz, 1 means 5 GHz. |
| """ |
| self.enter_option('30 %d' % band, '0x0') |
| returned_string = self.enter_option('29', 'GetModeAG: 0x0 :') |
| print 'Setting Frequency Band:' + returned_string |
| |
| |
| def set_channel(self, channel_no): |
| """Setting and verifying the channel.""" |
| self.enter_option('12 %d' % channel_no, '0x00000000') |
| returned_string = self.enter_option('11', 'RF Channel:') |
| print 'Setting RF Channel:' + returned_string |
| |
| |
| def count(self): |
| """Counting the packets and clearing the count.""" |
| self.labtool8797.sendline('32') |
| self.labtool8797.expect('Rx Packet') |
| |
| |
| def get_error_rate(self): |
| """Counting the packets and calculating the error rate.""" |
| self.count() |
| self.labtool8797.expect('Multi Cast') |
| rxpacket = float(self.labtool8797.before) |
| self.labtool8797.expect('Err Count') |
| multicast = float(self.labtool8797.before) |
| self.labtool8797.expect('Enter option:') |
| error = float(self.labtool8797.before) |
| error_rate = error / multicast |
| return (rxpacket, multicast, error, error_rate) |
| |
| |
| def exit_wifi_menu(self): |
| self.enter_option('99', 'Exit') |
| |
| |
| def exit_labtool(self): |
| self.labtool8797.sendline('99') |
| self.labtool8797.expect('Exiting') |
| |
| |
| def sweep_power_get_sensitivity(labtool, n4010a, rx_power): |
| """ |
| Interacting with N4010A and Labtool, finding the RX |
| sensitivity by sweeping the power down. |
| Receiver sensitivty is the minimum received power at |
| which the packet error rate (PER) shall not exceed 10%. |
| |
| @param labtool: call Labtool8797. |
| @param n4010a: call agilent_scpi.N4010ASCPI. |
| @param rx_power: the DUT received power sent by N4010A. |
| @return rx_sensitivity. |
| """ |
| error_rate = 0 |
| while error_rate < 0.1: |
| # Clearing count twice before transmitting |
| labtool.count() |
| labtool.count() |
| # N4010A starts to transmit |
| n4010a.set_amplitude(rx_power) |
| n4010a.output_on() |
| |
| # Getting received packet count and error rate |
| (rxpacket, multicast, error, error_rate) = ( |
| labtool.get_error_rate()) |
| print ('Rx Power: %d Rx Packet: %d Multi Cast: %d ' |
| 'Error Count: %d Error Rate: %.003f' % |
| (rx_power, rxpacket, multicast, |
| error, error_rate)) |
| # Sweeping the power down |
| rx_power -= 1 |
| |
| # Backing up 2 dB. When the while loop breaks, the rx_power |
| # still reduces 1 dB before exiting; also PER >= 10%, need |
| # to add 1dB to make PER < 10% |
| rx_sensitivity = rx_power + 2 |
| return rx_sensitivity |
| |
| |
| def find_sensitivity_for_channels_rates(n4010a, labtool, wifi_bands, |
| data_rate_power_info, TEST_2G, TEST_5G): |
| """ |
| Finding RX sensivity for different channels, data rates. |
| |
| @param n4010a: call agilent_scpi.N4010ASCPI. |
| @param labtool: call Labtool8797. |
| @param wifi_bands: the channels that would be tested. |
| @param data_rate_power_info: the matching table of the data rates. |
| and the starting power for the test. |
| @param TEST_2G: flag for enable or disable 2GHz test. |
| @param TEST_5G: flag for enable or disable 5GHz test. |
| """ |
| for band_info, channel_info in wifi_bands: |
| # Only run test when the 2G or 5G test flag is true |
| if (band_info == 0 and TEST_2G) or (band_info == 1 and TEST_5G): |
| labtool.set_band(band_info) |
| |
| for channel_no, freq in channel_info: |
| # Setting the channel on N4010A |
| n4010a.set_frequency(freq) |
| # Setting the channel on DUT |
| labtool.set_channel(channel_no) |
| |
| for data_rate, rx_power in data_rate_power_info: |
| # Selecting the waveform/sequence |
| n4010a.set_waveform(data_rate) |
| # Finding RX sensitivity |
| rx_sensitivity = sweep_power_get_sensitivity( |
| labtool, n4010a, rx_power) |
| print('RX Sensitivity at %s at channel %d = %d dBm\n' |
| %(data_rate, channel_no, rx_sensitivity)) |
| |
| |
| def connect_and_initialize_n4010a(n4010a): |
| print 'Connecting to %s' % args.n4010a_host |
| print 'Connected, Tester ID: %s' % n4010a.id |
| n4010a.initialize( |
| 'This instrument is being\noperated remotely by\nPython script') |
| print 'N4010A initialized' |
| |
| def launch_labtool(labtool): |
| labtool.enter_wifi_menu() |
| labtool.set_path(3) |
| |
| def cleanup(labtool, n4010a): |
| labtool.exit_wifi_menu() |
| labtool.exit_labtool() |
| n4010a.output_off() |
| n4010a.clear_message() |
| print 'Finished!' |
| |
| def main(): |
| # Short pause for putting DUT into the shieldbox |
| print 'Beginning test in %s secs' % args.sleeptime |
| time.sleep(float(args.sleeptime)) |
| |
| n4010a = agilent_scpi.N4010ASCPI(args.n4010a_host) |
| connect_and_initialize_n4010a(n4010a) |
| |
| labtool = Labtool8797(args.labtool_dir) |
| launch_labtool(labtool) |
| |
| # Finding RX sensivity for various channels, data rates |
| BAND_2G = 0 |
| BAND_5G = 1 |
| TEST_2G = True |
| TEST_5G = True |
| wifi_bands = ( |
| (BAND_2G, ((1, 2412*1e6), (6, 2437*1e6), (11, 2462*1e6))), |
| (BAND_5G, ((36, 5180*1e6), (64, 5320*1e6), (165, 5825*1e6)))) |
| data_rate_power_info = (('MCS0', -70), ('MCS7', -50)) |
| |
| find_sensitivity_for_channels_rates(n4010a, labtool, wifi_bands, |
| data_rate_power_info, TEST_2G, TEST_5G) |
| |
| cleanup(labtool, n4010a) |
| |
| |
| if __name__ == '__main__': |
| parser = argparse.ArgumentParser() |
| parser.add_argument('--sleep', '-s', dest='sleeptime', default=5, |
| help='pausing time for putting DUT into the shieldbox') |
| parser.add_argument('--host', dest='n4010a_host', |
| default='172.22.52.96', |
| help='the IP address of N4010A') |
| parser.add_argument('--dir', '-d', dest='labtool_dir', |
| default='/usr/local/third_party/marvell_labtool', |
| help='the labtool binary directory') |
| args = parser.parse_args() |
| main() |