1 # Copyright (c) 2012 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 10 class firmware_ECCharging(FirmwareTest): 11 """ 12 Servo based EC charging control test. 13 """ 14 version = 1 15 16 # Threshold of trickle charging current in mA 17 TRICKLE_CHARGE_THRESHOLD = 100 18 19 def initialize(self, host, cmdline_args): 20 super(firmware_ECCharging, self).initialize(host, cmdline_args) 21 # Only run in normal mode 22 self.switcher.setup_mode('normal') 23 self.ec.send_command("chan 0") 24 25 26 def cleanup(self): 27 try: 28 self.ec.send_command("chan 0xffffffff") 29 except Exception as e: 30 logging.error("Caught exception: %s", str(e)) 31 super(firmware_ECCharging, self).cleanup() 32 33 34 def _get_battery_desired_voltage(self): 35 """Get battery desired voltage value.""" 36 voltage = int(self.ec.send_command_get_output("battery", 37 ["V-desired:\s+0x[0-9a-f]*\s+=\s+(\d+)\s+mV"])[0][1]) 38 logging.info("Battery desired voltage = %d mV", voltage) 39 return voltage 40 41 42 def _get_battery_desired_current(self): 43 """Get battery desired current value.""" 44 current = int(self.ec.send_command_get_output("battery", 45 ["I-desired:\s+0x[0-9a-f]*\s+=\s+(\d+)\s+mA"])[0][1]) 46 logging.info("Battery desired current = %d mA", current) 47 return current 48 49 50 def _get_battery_actual_voltage(self): 51 """Get the actual voltage from charger to battery.""" 52 voltage = int(self.ec.send_command_get_output("battery", 53 ["V:\s+0x[0-9a-f]*\s+=\s+(\d+)\s+mV"])[0][1]) 54 logging.info("Battery actual voltage = %d mV", voltage) 55 return voltage 56 57 58 def _get_battery_actual_current(self): 59 """Get the actual current from charger to battery.""" 60 current = int(self.ec.send_command_get_output("battery", 61 ["I:\s+0x[0-9a-f]*\s+=\s+([0-9-]+)\s+mA"])[0][1]) 62 logging.info("Battery actual current = %d mA", current) 63 return current 64 65 66 def _get_battery_charge(self): 67 """Get battery charge state.""" 68 charge = int(self.ec.send_command_get_output("battery", 69 ["Charge:\s+(\d+)\s+"])[0][1]) 70 logging.info("Battery charge = %d %%", charge) 71 return charge 72 73 74 def _get_charger_target_voltage(self): 75 """Get target charging voltage set in charger.""" 76 voltage = int(self.ec.send_command_get_output("charger", 77 ["V_batt:\s+(\d+)\s"])[0][1]) 78 logging.info("Charger target voltage = %d mV", voltage) 79 return voltage 80 81 82 def _get_charger_target_current(self): 83 """Get target charging current set in charger.""" 84 current = int(self.ec.send_command_get_output("charger", 85 ["I_batt:\s+(\d+)\s"])[0][1]) 86 logging.info("Charger target current = %d mA", current) 87 return current 88 89 90 def _get_trickle_charging(self): 91 """Check if we are trickle charging battery.""" 92 return (self._get_battery_desired_current() < 93 self.TRICKLE_CHARGE_THRESHOLD) 94 95 96 def _check_target_value(self): 97 """Check charger target values are correct. 98 99 Raise: 100 error.TestFail: Raised when check fails. 101 """ 102 if (self._get_charger_target_voltage() >= 103 1.05 * self._get_battery_desired_voltage()): 104 raise error.TestFail("Charger target voltage is too high.") 105 if (self._get_charger_target_current() >= 106 1.05 * self._get_battery_desired_current()): 107 raise error.TestFail("Charger target current is too high.") 108 109 110 def _check_actual_value(self): 111 """Check actual voltage/current values are correct. 112 113 Raise: 114 error.TestFail: Raised when check fails. 115 """ 116 if (self._get_battery_actual_voltage() >= 117 1.05 * self._get_charger_target_voltage()): 118 raise error.TestFail("Battery actual voltage is too high.") 119 if (self._get_battery_actual_current() >= 120 1.05 * self._get_charger_target_current()): 121 raise error.TestFail("Battery actual current is too high.") 122 123 124 def run_once(self): 125 if not self.check_ec_capability(['battery', 'charging']): 126 raise error.TestNAError("Nothing needs to be tested on this device") 127 if self._get_battery_charge() == 100: 128 logging.info("Battery is full. Unable to test.") 129 return 130 if self._get_trickle_charging(): 131 logging.info("Trickling charging battery. Unable to test.") 132 return 133 if self._get_battery_actual_current() < 0: 134 raise error.TestFail("This test must be run with AC power.") 135 136 logging.info("Checking charger target values...") 137 self._check_target_value() 138 139 logging.info("Checking battery actual values...") 140 self._check_actual_value() 141