blob: 092245014cff885cbe586c22bb1f9c73d8fa4312 [file] [log] [blame]
Tom Wai-Hong Tam6019a1a2012-10-12 14:03:34 +08001# 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
Tom Wai-Hong Tam8326bff2012-10-12 15:34:38 +08005import ast, re
Tom Wai-Hong Tam6019a1a2012-10-12 14:03:34 +08006
7from autotest_lib.client.common_lib import error
8
Tom Wai-Hong Tam8326bff2012-10-12 15:34:38 +08009# en-US key matrix (from "kb membrane pin matrix.pdf")
10KEYMATRIX = {'`': (3, 1), '1': (6, 1), '2': (6, 4), '3': (6, 2), '4': (6, 3),
11 '5': (3, 3), '6': (3, 6), '7': (6, 6), '8': (6, 5), '9': (6, 9),
12 '0': (6, 8), '-': (3, 8), '=': (0, 8), 'q': (7, 1), 'w': (7, 4),
13 'e': (7, 2), 'r': (7, 3), 't': (2, 3), 'y': (2, 6), 'u': (7, 6),
14 'i': (7, 5), 'o': (7, 9), 'p': (7, 8), '[': (2, 8), ']': (2, 5),
15 '\\': (3, 11), 'a': (4, 1), 's': (4, 4), 'd': (4, 2), 'f': (4, 3),
16 'g': (1, 3), 'h': (1, 6), 'j': (4, 6), 'k': (4, 5), 'l': (4, 9),
17 ';': (4, 8), '\'': (1, 8), 'z': (5, 1), 'x': (5, 4), 'c': (5, 2),
18 'v': (5, 3), 'b': (0, 3), 'n': (0, 6), 'm': (5, 6), ',': (5, 5),
19 '.': (5, 9), '/': (5, 8), ' ': (5, 11), '<right>': (6, 12),
20 '<alt_r>': (0, 10), '<down>': (6, 11), '<tab>': (2, 1),
21 '<f10>': (0, 4), '<shift_r>': (7, 7), '<ctrl_r>': (4, 0),
22 '<esc>': (1, 1), '<backspace>': (1, 11), '<f2>': (3, 2),
23 '<alt_l>': (6, 10), '<ctrl_l>': (2, 0), '<f1>': (0, 2),
24 '<search>': (0, 1), '<f3>': (2, 2), '<f4>': (1, 2), '<f5>': (3, 4),
25 '<f6>': (2, 4), '<f7>': (1, 4), '<f8>': (2, 9), '<f9>': (1, 9),
26 '<up>': (7, 11), '<shift_l>': (5, 7), '<enter>': (4, 11),
27 '<left>': (7, 12)}
28
29
Tom Wai-Hong Tam665281c2012-10-30 11:55:10 +080030# Hostevent codes, copied from:
31# ec/include/ec_commands.h
32HOSTEVENT_LID_CLOSED = 0x00000001
33HOSTEVENT_LID_OPEN = 0x00000002
34HOSTEVENT_POWER_BUTTON = 0x00000004
35HOSTEVENT_AC_CONNECTED = 0x00000008
36HOSTEVENT_AC_DISCONNECTED = 0x00000010
37HOSTEVENT_BATTERY_LOW = 0x00000020
38HOSTEVENT_BATTERY_CRITICAL = 0x00000040
39HOSTEVENT_BATTERY = 0x00000080
40HOSTEVENT_THERMAL_THRESHOLD = 0x00000100
41HOSTEVENT_THERMAL_OVERLOAD = 0x00000200
42HOSTEVENT_THERMAL = 0x00000400
43HOSTEVENT_USB_CHARGER = 0x00000800
44HOSTEVENT_KEY_PRESSED = 0x00001000
45HOSTEVENT_INTERFACE_READY = 0x00002000
46# Keyboard recovery combo has been pressed
47HOSTEVENT_KEYBOARD_RECOVERY = 0x00004000
48# Shutdown due to thermal overload
49HOSTEVENT_THERMAL_SHUTDOWN = 0x00008000
50# Shutdown due to battery level too low
51HOSTEVENT_BATTERY_SHUTDOWN = 0x00010000
52HOSTEVENT_INVALID = 0x80000000
53
54
Tom Wai-Hong Tam6019a1a2012-10-12 14:03:34 +080055class ChromeEC(object):
56 """Manages control of a Chrome EC.
57
58 We control the Chrome EC via the UART of a Servo board. Chrome EC
59 provides many interfaces to set and get its behavior via console commands.
60 This class is to abstract these interfaces.
61 """
62
63 def __init__(self, servo):
64 """Initialize and keep the servo object.
65
66 Args:
67 servo: A Servo object.
68 """
69 self._servo = servo
Vic Yang0ef0c092012-11-02 15:28:54 +080070 self._cached_uart_regexp = None
71
72
73 def set_uart_regexp(self, regexp):
74 if self._cached_uart_regexp == regexp:
75 return
76 self._cached_uart_regexp = regexp
77 self._servo.set('ec_uart_regexp', regexp)
Tom Wai-Hong Tam6019a1a2012-10-12 14:03:34 +080078
79
80 def send_command(self, command):
81 """Send command through UART.
82
83 This function opens UART pty when called, and then command is sent
84 through UART.
85
86 Args:
87 command: The command string to send.
88 """
Vic Yang0ef0c092012-11-02 15:28:54 +080089 self.set_uart_regexp('None')
Tom Wai-Hong Tam6019a1a2012-10-12 14:03:34 +080090 self._servo.set_nocheck('ec_uart_cmd', command)
91
92
Vadim Bendebury5c8f8672013-01-17 17:47:15 -080093 def send_command_get_output(self, command, regexp_list):
Tom Wai-Hong Tam6019a1a2012-10-12 14:03:34 +080094 """Send command through UART and wait for response.
95
96 This function waits for response message matching regular expressions.
97
98 Args:
99 command: The command sent.
100 regexp_list: List of regular expressions used to match response
101 message. Note, list must be ordered.
102
103 Returns:
104 List of tuples, each of which contains the entire matched string and
105 all the subgroups of the match. None if not matched.
106 For example:
107 response of the given command:
108 High temp: 37.2
109 Low temp: 36.4
110 regexp_list:
111 ['High temp: (\d+)\.(\d+)', 'Low temp: (\d+)\.(\d+)']
112 returns:
113 [('High temp: 37.2', '37', '2'), ('Low temp: 36.4', '36', '4')]
114
115 Raises:
116 error.TestError: An error when the given regexp_list is not valid.
117 """
118 if not isinstance(regexp_list, list):
119 raise error.TestError('Arugment regexp_list is not a list: %s' %
120 str(regexp_list))
121
Vic Yang0ef0c092012-11-02 15:28:54 +0800122 self.set_uart_regexp(str(regexp_list))
Tom Wai-Hong Tam6019a1a2012-10-12 14:03:34 +0800123 self._servo.set_nocheck('ec_uart_cmd', command)
124 return ast.literal_eval(self._servo.get('ec_uart_cmd'))
Tom Wai-Hong Tam8326bff2012-10-12 15:34:38 +0800125
126
127 def key_down(self, keyname):
128 """Simulate pressing a key.
129
130 Args:
131 keyname: Key name, one of the keys of KEYMATRIX.
132 """
133 self.send_command('kbpress %d %d 1' %
134 (KEYMATRIX[keyname][1], KEYMATRIX[keyname][0]))
135
136
137 def key_up(self, keyname):
138 """Simulate releasing a key.
139
140 Args:
141 keyname: Key name, one of the keys of KEYMATRIX.
142 """
143 self.send_command('kbpress %d %d 0' %
144 (KEYMATRIX[keyname][1], KEYMATRIX[keyname][0]))
145
146
147 def key_press(self, keyname):
148 """Press and then release a key.
149
150 Args:
151 keyname: Key name, one of the keys of KEYMATRIX.
152 """
153 self.key_down(keyname)
154 self.key_up(keyname)
155
156
157 def send_key_string_raw(self, string):
158 """Send key strokes consisting of only characters.
159
160 Args:
161 string: Raw string.
162 """
163 for c in string:
164 self.key_press(c)
165
166
167 def send_key_string(self, string):
168 """Send key strokes including special keys.
169
170 Args:
171 string: Character string including special keys. An example
172 is "this is an<tab>example<enter>".
173 """
174 for m in re.finditer("(<[^>]+>)|([^<>]+)", string):
175 sp, raw = m.groups()
176 if raw is not None:
177 self.send_key_string_raw(raw)
178 else:
179 self.key_press(sp)
Tom Wai-Hong Tambb92e6c2012-10-30 11:06:09 +0800180
181
182 def reboot(self, flags=''):
183 """Reboot EC with given flags.
184
185 Args:
186 flags: Optional, a space-separated string of flags passed to the
187 reboot command, including:
188 default: EC soft reboot;
189 'hard': EC hard/cold reboot;
190 'ap-off': Leave AP off after EC reboot (by default, EC turns
191 AP on after reboot if lid is open).
192
193 Raises:
194 error.TestError: If the string of flags is invalid.
195 """
196 for flag in flags.split():
197 if flag not in ('hard', 'ap-off'):
198 raise error.TestError(
199 'The flag %s of EC reboot command is invalid.' % flag)
200 self.send_command("reboot %s" % flags)
Tom Wai-Hong Tam05574ee2012-10-30 11:34:21 +0800201
202
203 def set_flash_write_protect(self, enable):
204 """Set the software write protect of EC flash.
205
206 Args:
207 enable: True to enable write protect, False to disable.
208 """
209 if enable:
210 self.send_command("flashwp enable")
211 else:
212 self.send_command("flashwp disable")
Tom Wai-Hong Tam665281c2012-10-30 11:55:10 +0800213
214
215 def set_hostevent(self, codes):
216 """Set the EC hostevent codes.
217
218 Args:
219 codes: Hostevent codes, HOSTEVENT_*
220 """
221 self.send_command("hostevent set %#x" % codes)