Home | History | Annotate | Download | only in firmware_PDConnect
      1 # Copyright 2015 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import logging
      6 
      7 from autotest_lib.client.common_lib import error
      8 from autotest_lib.server.cros.faft.firmware_test import FirmwareTest
      9 from autotest_lib.server.cros.servo import pd_device
     10 
     11 
     12 class firmware_PDConnect(FirmwareTest):
     13     """
     14     Servo based USB PD connect/disconnect test. If Plankton is not one
     15     of the device pair elements, then this test requires that at least
     16     one of the devices support dual role mode in order to force a disconnect
     17     to connect sequence. The test does not depend on the DUT acting as source
     18     or sink, either mode should pass.
     19 
     20     Pass critera is 100%  of connections resulting in successful connections
     21     """
     22     version = 1
     23     CONNECT_ITERATIONS = 10
     24     def _test_connect(self, port_pair):
     25         """Tests disconnect/connect sequence
     26 
     27         @param port_pair: list of 2 connected PD devices
     28         """
     29         # Delay in seconds between disconnect and connect commands
     30         RECONNECT_DELAY = 2
     31         for dev in port_pair:
     32             for attempt in xrange(self.CONNECT_ITERATIONS):
     33                 logging.info('Disconnect/Connect iteration %d', attempt)
     34                 try:
     35                     if dev.drp_disconnect_connect(RECONNECT_DELAY) == False:
     36                         raise error.TestFail('Disconnect/Connect Failed')
     37                 except NotImplementedError:
     38                     logging.warn('Device does not support disconnect/connect')
     39                     break
     40 
     41     def initialize(self, host, cmdline_args):
     42         super(firmware_PDConnect, self).initialize(host, cmdline_args)
     43         # Only run in normal mode
     44         self.switcher.setup_mode('normal')
     45         self.usbpd.enable_console_channel('usbpd')
     46 
     47 
     48     def cleanup(self):
     49         self.usbpd.send_command('chan 0xffffffff')
     50         super(firmware_PDConnect, self).cleanup()
     51 
     52 
     53     def run_once(self):
     54         """Exectue disconnect/connect sequence test
     55 
     56         """
     57 
     58         # Create list of available UART consoles
     59         consoles = [self.usbpd, self.plankton]
     60         port_partner = pd_device.PDPortPartner(consoles)
     61         # Identify a valid test port pair
     62         port_pair = port_partner.identify_pd_devices()
     63         if not port_pair:
     64             raise error.TestFail('No PD connection found!')
     65 
     66         # Test disconnect/connect sequences
     67         self._test_connect(port_pair)
     68         # Swap power roles (if possible). Note the pr swap is attempted
     69         # for both devices in the connection. This ensures that a device
     70         # such as Plankton, which is dualrole capable, but has this mode
     71         # disabled by default, won't prevent the device pair from role swapping.
     72         swap = False;
     73         for dev in port_pair:
     74             try:
     75                 if dev.pr_swap():
     76                     swap = True
     77                     break
     78             except NotImplementedError:
     79                 logging.warn('device cant send power role swap command')
     80         if swap == True:
     81             # Power role has been swapped, retest.
     82             self._test_connect(port_pair)
     83         else:
     84             logging.warn('Device pair could not role swap, ending test')
     85