1fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott# Copyright 2015 The Chromium OS Authors. All rights reserved. 2fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott# Use of this source code is governed by a BSD-style license that can be 3fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott# found in the LICENSE file. 4fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 5fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scottimport logging 6fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scottimport time 7fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 8fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scottfrom autotest_lib.client.common_lib import error 9fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scottfrom autotest_lib.server.cros.faft.firmware_test import FirmwareTest 10fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scottfrom autotest_lib.server.cros.servo import pd_console 11fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 12fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 13fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scottclass firmware_PDConnect(FirmwareTest): 14fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott """ 15fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott Servo based USB PD connect/disconnect test. This test is written 16fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott for the DUT and requires that the DUT support dualrole (SRC or SNK) 17fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott operation in order to force a disconnect and connect event. The test 18fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott does not depend on the DUT acting as source or sink, either mode 19fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott should pass. 20fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 21fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott Pass critera is 100% of connections resulting in successful connections 22fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 23fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott """ 24fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott version = 1 25fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 26fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 27fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott def initialize(self, host, cmdline_args): 28fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott super(firmware_PDConnect, self).initialize(host, cmdline_args) 29fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott # Only run in normal mode 30fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott self.switcher.setup_mode('normal') 31fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott self.usbpd.send_command("chan 0") 32fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 33fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 34fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott def cleanup(self): 35fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott self.usbpd.send_command("chan 0xffffffff") 36fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott super(firmware_PDConnect, self).cleanup() 37fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 38fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 39fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott def _test_pd_connection(self, connect_state, port): 40fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott """Verify current pd state matches the expected value. 41fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 42fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott The current state will be read up to 2 times. This 43fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott may not be required, but during development testing 44fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott instances were observed where state reads on glados 45fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott did not give the full state string which would then 46fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott applear to be a failure even though the type C connection 47fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott had been made. 48fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 49fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott @params connect_state: Expected state string 50fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott @params port: port number <0/1> to query 51fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott @returns: True if state matches, false otherwise 52fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott """ 53fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott for attempts in range(1,3): 54fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott pd_state = self.pd.get_pd_state(self.port) 55fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott if pd_state == connect_state: 56fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott return True 57fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott return False 58fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 59fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 60fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott def run_once(self): 61fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott """Exectue disconnect/connect sequence test 62fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 63fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott """ 64fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott # delay between test iterations 65fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott DUALROLE_SET_DELAY = 2 66fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 67fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott # create objects for pd utilities 68fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott self.pd = pd_console.PDConsoleUtils(self.usbpd) 69fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 70fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott # Make sure PD support exists in the UART console 71fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott if self.pd.verify_pd_console() == False: 72fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott raise error.TestFail("pd command not present on console!") 73fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 74fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott # Enable dualrole mode 75fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott self.pd.set_pd_dualrole('on') 76fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott time.sleep(DUALROLE_SET_DELAY) 77fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 78fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott # Type C connection (PD contract) should exist at this point 79fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott connect_status = self.pd.query_pd_connection() 80fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott if connect_status['connect'] == False: 81fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott raise error.TestFail("pd connection not found") 82fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott # Record port where type C connection was detected 83fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott self.port = connect_status['port'] 84fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott # Save the SRC vs SNK state 85fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott connect_state = connect_status['role'] 86fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 87fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott logging.info('Type C connection detected on Port %d: %r', 88fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott self.port, connect_state) 89fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 90fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott # determine the dualrole command to connect/disconnect 91fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott if connect_state == 'SRC_READY': 92fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott disc_cmd = 'snk' 93fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott connect_cmd = 'src' 94fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott else: 95fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott disc_cmd = 'src' 96fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott connect_cmd = 'snk' 97fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 98fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott # counter used for successful iterations 99fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott success = 0 100fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott total_attempts = 100 101fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 102fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott # Attempt connect/disconnect iterations 103fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott for test_count in range(1, total_attempts + 1): 104fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott logging.info ('\n************ Iteration %r ***************', 105fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott test_count) 106fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott # Force Type C disconnect 107fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott self.pd.set_pd_dualrole(disc_cmd) 108fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott time.sleep(DUALROLE_SET_DELAY) 109fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott # Attempt to reconnect 110fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott self.pd.set_pd_dualrole(connect_cmd) 111fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott time.sleep(DUALROLE_SET_DELAY) 112fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott # Verify connection was successful 113fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott if self._test_pd_connection(connect_state, self.port) == True: 114fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott success += 1 115fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 116fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott self.pd.set_pd_dualrole('on') 117fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott logging.info ('************ Connection Stats ***************') 118fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott logging.info ('Attempts = %d: Connections = %d', test_count, success) 119fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott logging.info ('*********************************************') 120fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott if success != total_attempts: 121fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott raise error.TestFail("Attempts = " + str(total_attempts) + 122fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott ': Success = ' + str(success)) 123fe06ed8afdd7323a1f3ee60c746b5c0335c659c0Scott 124