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