blob: 244bccdffd790f774b2218b884f7d2dec0bce295 [file] [log] [blame]
# Copyright 2019 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
import time
from autotest_lib.client.common_lib import error
from autotest_lib.server.cros.faft.cr50_test import Cr50Test
class firmware_Cr50DeferredECReset(Cr50Test):
"""Verify EC_RST_L stays asserted only if all conditions below are True.
(1) System got 'Power-On reset'.
(2) RDD cable is connected.
(3) The power button is held.
After this, EC_RST_L should be deasserted as soon as the power button
gets released.
"""
version = 1
def initialize(self, host, cmdline_args, full_args):
"""Initialize the test and check if
cr50 is exists,
DTS is controllable, and
power delivery mode and power button is adjustable.
"""
super(firmware_Cr50DeferredECReset, self).initialize(host, cmdline_args,
full_args)
if not hasattr(self, 'cr50'):
raise error.TestNAError('Test can only be run on devices with '
'access to the Cr50 console')
if not self.cr50.servo_v4_supports_dts_mode():
raise error.TestNAError('Need working servo v4 DTS control')
self.fast_open(enable_testlab=True)
if not self.cr50.testlab_is_on():
raise error.TestNAError('Cr50 testlab mode needs to be enabled')
# Test the external power delivery
self.servo.set('servo_v4_role', 'snk')
time.sleep(3)
rv = self.ec.send_command_get_output('chgstate',['.*>'])[0].strip()
logging.info(rv)
if not 'ac = 0' in rv:
raise error.TestFail('Failed in setting servo_v4_role sink')
# Test stopping the external power delivery
self.servo.set('servo_v4_role', 'src')
time.sleep(3)
rv = self.ec.send_command_get_output('chgstate',['.*>'])[0].strip()
logging.info(rv)
if not 'ac = 1' in rv:
raise error.TestFail('Failed in setting servo_v4_role source')
# Test if the power button is adjustable.
self.servo.set('pwr_button', 'press')
self.servo.set('pwr_button', 'release')
def check_ecrst_asserted(self, expect_assert):
"""Ask CR50 whether EC_RST_L is asserted or deasserted.
Args:
expect_assert: True if it is expected asserted.
False otherwise.
"""
# If the console is responsive, then the EC is awake.
rv = self.cr50.send_command_get_output('ecrst',
['EC_RST_L is \w{0,2}asserted.*>'])[0].strip()
logging.info(rv)
expecting_txt = ' asserted' if expect_assert else ' deasserted'
if not expecting_txt in rv:
raise error.TestFail(rv)
def ping_ec(self, expect_response):
"""Check if EC is running and responding.
Args:
expect_response: True if EC should respond
False otherwise.
"""
try:
rv = self.ec.send_command_get_output('time',
['time.*>'])[0].strip()
except error.TestFail as e:
logging.info(e)
if 'Timeout waiting for response' in str(e):
if not expect_response:
return
raise e
else:
if not expect_response:
raise error.TestFail(rv)
def test_deferred_ec_reset(self, power_button_hold, rdd_enable,
expect_ec_response):
"""Do a power-on reset, and check if EC responds.
Args:
power_button_hold: True if it should be pressed on a system reset.
False otherwise.
rdd_enable: True if RDD should be detected on a system reset.
False otherwise.
expect_ec_response: True if EC should run and response on a system
reset.
False otherwise.
"""
logging.info('Test deferred_ec_reset starts.')
logging.info('Power button held: %s', power_button_hold)
logging.info('RDD connection : %s', rdd_enable)
# Stop power delivery to DUT
self.servo.set('servo_v4_role', 'snk')
time.sleep(3)
# Battery Cutoff
self.ec.send_command('cutoff')
time.sleep(3)
# EC should not respond
self.ping_ec(False)
# press (or release) the power button
power_button_setval = 'press' if power_button_hold else 'release'
# call set_nocheck, since power button shall be recognized as pressed
# at this point.
self.servo.set_nocheck('pwr_button', power_button_setval)
# enable RDD Connection (or disable)
self.servo.set_nocheck('servo_v4_dts_mode',
'on' if rdd_enable else 'off')
time.sleep(self.cr50.SHORT_WAIT)
# Enable power delivery to DUT
self.servo.set('servo_v4_role', 'src')
# Wait for a while
wait_sec = 30
logging.info('waiting for %d seconds', wait_sec)
time.sleep(wait_sec)
# Check if EC_RST_L is asserted (or deasserted) and EC is on (or off).
self.check_ecrst_asserted(not expect_ec_response)
self.ping_ec(expect_ec_response)
# Release power button
self.servo.set('pwr_button', 'release')
# Check if EC_RST_L is deasserted and EC is on.
self.check_ecrst_asserted(False)
self.ping_ec(True)
# Recover CCD
if self.servo.get('servo_v4_dts_mode') == 'off':
self.cr50.ccd_enable()
def run_once(self):
"""Test deferred EC reset feature. """
# Release power button and disable RDD on power-on reset.
# EC should be running.
self.test_deferred_ec_reset(power_button_hold=False, rdd_enable=False,
expect_ec_response=True)
# Release power button but enable RDD on power-on reset.
# EC should be running.
self.test_deferred_ec_reset(power_button_hold=False, rdd_enable=True,
expect_ec_response=True)
# Hold power button but disable RDD on power-on reset.
# EC should be running.
self.test_deferred_ec_reset(power_button_hold=True, rdd_enable=False,
expect_ec_response=True)
# Hold power button and enable RDD on power-on reset.
# EC should not be running.
self.test_deferred_ec_reset(power_button_hold=True, rdd_enable=True,
expect_ec_response=False)