Exemplo n.º 1
0
    def run_once(self):
        """Compares VBUS voltage and current with charging setting.

        When charging voltage == 0, Plankton will act as a power sink and draws
        5 volts from DUT. Other charging voltage should be seen on USB type C
        VBUS INA meter in a 12% range.

        When charging voltage == 5, Plankton INA current should be seen around
        3 Amps (we set the range among 2 ~ 3.4 Amps just as in factory testing).
        Other positive charging votage should not be less than 0 Amp.

        @raise TestFail: If VBUS voltage or current is not in range.
        """
        self.pd_console_utils = pd_console.PDConsoleUtils(self.plankton)

        for charging_voltage in self.plankton.get_charging_voltages():
            self.plankton.charge(charging_voltage)
            time.sleep(self.VBUS_CHANGE_DELAY)
            pd_state = self.pd_console_utils.get_pd_state(0)
            if charging_voltage > 0:
                expected_state = self.pd_console_utils.SRC_CONNECT
            else:
                expected_state = self.pd_console_utils.SNK_CONNECT
            logging.info('Plankton state = %s', pd_state)
            if pd_state != expected_state:
                raise error.TestFail('PD state != expected state, (%s != %s)' %
                                     (pd_state, expected_state))
            expected_vbus_voltage = float(charging_voltage if charging_voltage
                                          > 0 else self.USBC_SINK_VOLTAGE)
            tolerance = self.VBUS_TOLERANCE * expected_vbus_voltage
            vbus_voltage = self.plankton.vbus_voltage
            vbus_current = self.plankton.vbus_current
            logging.info('Charging %dV: VBUS V=%f I=%f', charging_voltage,
                         vbus_voltage, vbus_current)

            if math.fabs(expected_vbus_voltage - vbus_voltage) > tolerance:
                raise error.TestFail(
                    'VBUS voltage out of range: %f (%f, delta %f)' %
                    (vbus_voltage, expected_vbus_voltage, tolerance))

            if charging_voltage == 0 and vbus_current > 0:
                raise error.TestFail('Failed to consume power from DUT')

            if charging_voltage > 0 and vbus_current <= 0:
                raise error.Testfail(
                    'VBUS current less than 0 in %d volt: %f' %
                    (charging_voltage, vbus_current))

            if (charging_voltage == 5
                    and (vbus_current < self.VBUS_5V_CURRENT_RANGE[0]
                         or vbus_current > self.VBUS_5V_CURRENT_RANGE[1])):
                raise error.TestFail(
                    'VBUS current out of range in 5 volt: %f %r' %
                    (vbus_current, self.VBUS_5V_CURRENT_RANGE))
Exemplo n.º 2
0
    def __init__(self, console, port):
        """Initialization method

        @param console: UART console object
        @param port: USB PD port number
        """
        # Save UART console
        self.console = console
        # Instantiate PD utilities used by methods in this class
        self.utils = pd_console.PDConsoleUtils(console)
        # Save the PD port number for this device
        self.port = port
        # Not a Plankton device
        self.is_plankton = False
Exemplo n.º 3
0
    def run_once(self):
        """Exectue disconnect/connect sequence test

        """
        # delay between test iterations
        DUALROLE_SET_DELAY = 2

        # create objects for pd utilities
        self.pd = pd_console.PDConsoleUtils(self.usbpd)

        # Make sure PD support exists in the UART console
        if self.pd.verify_pd_console() == False:
            raise error.TestFail("pd command not present on console!")

        # Enable dualrole mode
        self.pd.set_pd_dualrole('on')
        time.sleep(DUALROLE_SET_DELAY)

        # Type C connection (PD contract) should exist at this point
        connect_status = self.pd.query_pd_connection()
        if connect_status['connect'] == False:
            raise error.TestFail("pd connection not found")
        # Record port where type C connection was detected
        self.port = connect_status['port']
        # Save the SRC vs SNK state
        connect_state = connect_status['role']

        logging.info('Type C connection detected on Port %d: %r', self.port,
                     connect_state)

        # determine the dualrole command to connect/disconnect
        if connect_state == 'SRC_READY':
            disc_cmd = 'snk'
            connect_cmd = 'src'
        else:
            disc_cmd = 'src'
            connect_cmd = 'snk'

        # counter used for successful iterations
        success = 0
        total_attempts = 100

        # Attempt connect/disconnect iterations
        for test_count in range(1, total_attempts + 1):
            logging.info('\n************ Iteration %r ***************',
                         test_count)
            # Force Type C disconnect
            self.pd.set_pd_dualrole(disc_cmd)
            time.sleep(DUALROLE_SET_DELAY)
            # Attempt to reconnect
            self.pd.set_pd_dualrole(connect_cmd)
            time.sleep(DUALROLE_SET_DELAY)
            # Verify connection was successful
            if self._test_pd_connection(connect_state, self.port) == True:
                success += 1

        self.pd.set_pd_dualrole('on')
        logging.info('************ Connection Stats ***************')
        logging.info('Attempts = %d: Connections = %d', test_count, success)
        logging.info('*********************************************')
        if success != total_attempts:
            raise error.TestFail("Attempts = " + str(total_attempts) +
                                 ': Success = ' + str(success))
    def run_once(self):
        """Exectue VBUS request test.

        """

        # create objects for pd utilities
        pd_dut_utils = pd_console.PDConsoleUtils(self.usbpd)
        pd_plankton_utils = pd_console.PDConsoleUtils(self.plankton)

        # Make sure PD support exists in the UART console
        if pd_dut_utils.verify_pd_console() == False:
            raise error.TestFail("pd command not present on console!")

        # Type C connection (PD contract) should exist at this point
        dut_state = pd_dut_utils.query_pd_connection()
        logging.info('DUT PD connection state: %r', dut_state)
        if dut_state['connect'] == False:
            raise error.TestFail("pd connection not found")
        if dut_state['role'] != pd_dut_utils.SNK_CONNECT:
            # DUT needs to be in SINK Mode, attempt to force change
            pd_dut_utils.set_pd_dualrole('snk')
            time.sleep(self.PD_SETTLE_DELAY)
            if pd_dut_utils.get_pd_state(dut_state['port']) != pd_dut_utils.SNK_CONNECT:
                raise error.TestFail("DUT not able to connect in SINK mode")

        # Plankton must be set to 20V SRC mode in order for the DUT
        # to be able to request all 3 possible voltage levels (5, 12, 20).
        # The DUT must be in SNK mode for the pd <port> dev <voltage>
        # command to have an effect.
        self.plankton.charge(self.USBC_MAX_VOLTAGE)
        time.sleep(self.PD_SETTLE_DELAY)
        logging.info('Start of DUT initiated tests')
        dut_failures = []
        for v in self.VOLTAGE_SEQUENCE:
            # Build 'pd <port> dev <voltage> command
            cmd = 'pd %d dev %d' % (dut_state['port'], v)
            pd_dut_utils.send_pd_command(cmd)
            time.sleep(self.PD_SETTLE_DELAY)
            result, result_str = self._compare_vbus(v)
            logging.info('%s, %s', result_str, result)
            if result == 'FAIL':
                dut_failures.append(result_str)

        # Make sure Plankton is set back to 20VSRC so DUT will accept all options
        cmd = 'pd %d dev %d' % (dut_state['port'], self.USBC_MAX_VOLTAGE)
        time.sleep(self.PD_SETTLE_DELAY)
        # The next group of tests need DUT to connect in SNK and SRC modes
        pd_dut_utils.set_pd_dualrole('on')

        plankton_failures = []
        logging.info('Start Plankton initiated tests')
        for voltage in self.plankton.get_charging_voltages():
            logging.info('********* %r *********', voltage)
            # Set charging voltage
            self.plankton.charge(voltage)
            # Wait for new PD contract to be established
            time.sleep(self.PD_SETTLE_DELAY)
            # Get current Plankton PD state
            plankton_state = pd_plankton_utils.get_pd_state(0)
            expected_vbus_voltage = self.plankton.charging_voltage
            # If Plankton is sink, then Vbus_exp = 5v
            if plankton_state == pd_plankton_utils.SNK_CONNECT:
                expected_vbus_voltage = self.USBC_SINK_VOLTAGE
            result, result_str = self._compare_vbus(expected_vbus_voltage)
            logging.info('%s, %s', result_str, result)
            if result == 'FAIL':
                plankton_failures.append(result_str)

        if dut_failures:
            logging.error('DUT voltage request failures')
            for fail in dut_failures:
                logging.error('%s', fail)

        if plankton_failures:
            logging.error('Plankton voltage source cap failures')
            for fail in plankton_failures:
                logging.error('%s', fail)

        if dut_failures or plankton_failures:
            if dut_failures and plankton_failures:
                test = 'DUT and Plankton'
                number = len(dut_failures) + len(plankton_failures)
            elif dut_failures:
                test = 'DUT'
                number = len(dut_failures)
            else:
                test = 'Plankton'
                number = len(plankton_failures)
            raise error.TestFail('%s failed %d times' % (test, number))
Exemplo n.º 5
0
    def run_once(self):
        """Execute Power Role swap test.

        1. Verify that pd console is accessible
        2. Verify that DUT has a valid PD contract and connected to Plankton
        3. Determine if DUT is in dualrole mode
        4. If not dualrole mode, verify DUT rejects power swap request
           Else test power swap (tx/rx), then Force DUT to be sink or
           source only and verify rejecttion of power swap request.

        """
        # create objects for pd utilities
        self.dut_pd_utils = pd_console.PDConsoleUtils(self.usbpd)
        self.plankton_pd_utils = pd_console.PDConsoleUtils(self.plankton)
        self.connect_utils = pd_console.PDConnectionUtils(
            self.dut_pd_utils, self.plankton_pd_utils)

        # Make sure PD support exists in the UART console
        if self.dut_pd_utils.verify_pd_console() == False:
            raise error.TestFail("pd command not present on console!")

        # Type C connection (PD contract) should exist at this point
        # For this test, the DUT must be connected to a Plankton.
        pd_port = self.connect_utils.find_dut_to_plankton_connection()
        if pd_port is None:
            raise error.TestFail("DUT to Plankton PD connection not found")
        dut_connect_state = self.dut_pd_utils.get_pd_state(pd_port)
        logging.info('Initial DUT connect state = %s', dut_connect_state)

        # Get DUT dualrole status
        if self.dut_pd_utils.is_pd_dual_role_enabled() == False:
            # DUT does not support dualrole mode, power swap
            # requests to the DUT should be rejected.
            logging.info('Power Swap support not advertised by DUT')
            self._test_power_swap_reject(pd_port)
            logging.info('Power Swap request rejected by DUT as expected')
        else:
            # Start with Plankton as source
            if self._set_plankton_power_role_to_src() == False:
                raise error.TestFail('Plankton not set to source')
            # DUT is dualrole in dual role mode. Test power role swap
            # operation intiated both by the DUT and Plankton.
            success = 0
            for attempt in xrange(self.POWER_SWAP_ITERATIONS):
                if attempt & 1:
                    direction = 'rx'
                else:
                    direction = 'tx'
                if self._attempt_power_swap(pd_port, direction):
                    success += 1
                new_state = self.dut_pd_utils.get_pd_state(pd_port)
                logging.info('New DUT power role = %s', new_state)

            if success != self.POWER_SWAP_ITERATIONS:
                raise error.TestFail('Failed %r power swap attempts' %
                                     (self.POWER_SWAP_ITERATIONS - success))

            # Force DUT to only support current power role
            if new_state == self.SRC:
                dual_mode = 'src'
            else:
                dual_mode = 'snk'
            logging.info('Setting dualrole mode to %s', dual_mode)
            self.dut_pd_utils.set_pd_dualrole(dual_mode)
            time.sleep(self.PD_ROLE_DELAY)
            # Expect behavior now is that DUT will reject power swap
            self._test_power_swap_reject(pd_port)
            logging.info('Power Swap request rejected by DUT as expected')
            # Restore DUT dual role operation
            self.dut_pd_utils.set_pd_dualrole('on')
            # Set connection back to default arrangement
            self.plankton_pd_utils.set_pd_dualrole('off')
            self.plankton_pd_utils.send_pd_command('fake disconnect 100 1000')
Exemplo n.º 6
0
    def run_once(self):
        """Exectue Data Role swap test.

        1. Verify that pd console is accessible
        2. Verify that DUT has a valid PD contract
        3. Determine if DUT advertises support for data swaps
        4. Test DUT initiated and received data swaps
        5. Swap power roles if supported
        6. Repeat DUT received data swap requests

        """
        # create objects for pd utilities
        self.dut_pd_utils = pd_console.PDConsoleUtils(self.usbpd)
        self.plankton_pd_utils = pd_console.PDConsoleUtils(self.plankton)

        # Make sure PD support exists in the UART console
        if self.dut_pd_utils.verify_pd_console() == False:
            raise error.TestFail("pd command not present on console!")

        # Type C connection (PD contract) should exist at this point
        # For this test, the DUT must be connected to a Plankton.
        pd_port = self._find_dut_to_plankton_connection()
        if pd_port == None:
            raise error.TestFail("DUT to Plankton PD connection not found")
        dut_connect_state = self.dut_pd_utils.get_pd_state(pd_port)
        logging.info('Initial DUT connect state = %s', dut_connect_state)

        # Determine if DUT supports data role swaps
        dr_swap_allowed = self.plankton_pd_utils.is_pd_flag_set(
            self.PLANKTON_PORT, 'data_swap')
        # Get current DUT data role
        dut_data_role = self._get_data_role(self.dut_pd_utils, pd_port)
        logging.info('Starting DUT Data Role = %r', dut_data_role)

        # If data swaps are not allowed on the DUT, then still
        # attempt a data swap and verify that the request is
        # rejected by the DUT and that it remains connected and
        # in the same role.
        if dr_swap_allowed == False:
            logging.info('Data Swap support not advertised by DUT')
            self._test_data_swap_reject(pd_port)
            logging.info('Data Swap request rejected by DUT as expected')
        else:
            # Data role swap support advertised, test this feature.
            self._execute_data_role_swap_test(pd_port)

            # If DUT supports Power Role swap then attempt to change roles.
            # This way, data role swaps will be tested in both configurations.
            if self.plankton_pd_utils.is_pd_flag_set(self.PLANKTON_PORT,
                                                     'power_swap'):
                logging.info('\nDUT advertises Power Swap Support')
                # Attempt to swap power roles
                power_swap = self._change_dut_power_role(pd_port)
                if power_swap:
                    self._execute_data_role_swap_test(pd_port)
                else:
                    logging.warn('Power swap not successful!')
                    logging.warn('Only tested with DUT in %s state',
                                 dut_connect_state)
            else:
                logging.info('DUT does not advertise power swap support')

            logging.info('***************** Swap Results ********************')
            total_attempts = 0
            total_failures = 0
            for direction, role in self.swap_attempt.iterkeys():
                logging.info('%s %s swap attempts = %d, failures = %d',
                             direction, role,
                             self.swap_attempt[(direction, role)],
                             self.swap_failure[(direction, role)])
                total_attempts += self.swap_attempt[(direction, role)]
                total_failures += self.swap_failure[(direction, role)]

            # If any swap attempts were not successful, flag test as failure
            if total_failures:
                raise error.TestFail(
                    'Data Swap Fail: Attempt = %d, Failure = %d' %
                    (total_attempts, total_failures))