1# Copyright 2017 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
6import re
7
8from autotest_lib.client.cros import ec
9from autotest_lib.server.cros.servo import chrome_ec
10
11
12class ChromeBaseEC(chrome_ec.ChromeConsole):
13    """Manages control of a ChromeBaseEC.
14
15    The ChromeBaseEC object should be instantiated via the create_base_ec()
16    method which checks the board name.
17
18    There are several ways to control the Base EC, depending on the setup.
19    To simplify, this class assumes the Base EC is connected to a servo-micro
20    flex to a servo v4 board. The main EC is also connected to the same servo
21    v4 board via either another servo-micro flex or the type-C CCD cable.
22
23    """
24
25    def __init__(self, servo, board):
26        """Initialize the object.
27
28        Args:
29          servo: An autotest_lib.server.cros.servo.Servo object.
30          board: A string of the board name for the base, e.g. "hammer".
31        """
32        self.board = board
33        console_prefix = board + '_ec_uart'
34        super(ChromeBaseEC, self).__init__(servo, console_prefix)
35
36
37    def get_board(self):
38        """Get the board name of the Base EC.
39
40        Returns:
41          A string of the board name.
42        """
43        return self.board
44
45
46    def key_down(self, keyname):
47        """Simulate pressing a key.
48
49        Args:
50          keyname: Key name, one of the keys of ec.KEYMATRIX.
51        """
52        self.send_command('kbpress %d %d 1' %
53                (ec.KEYMATRIX[keyname][1], ec.KEYMATRIX[keyname][0]))
54
55
56    def key_up(self, keyname):
57        """Simulate releasing a key.
58
59        Args:
60          keyname: Key name, one of the keys of KEYMATRIX.
61        """
62        self.send_command('kbpress %d %d 0' %
63                (ec.KEYMATRIX[keyname][1], ec.KEYMATRIX[keyname][0]))
64
65
66    def key_press(self, keyname):
67        """Press and then release a key.
68
69        Args:
70          keyname: Key name, one of the keys of KEYMATRIX.
71        """
72        self.send_command([
73                'kbpress %d %d 1' %
74                    (ec.KEYMATRIX[keyname][1], ec.KEYMATRIX[keyname][0]),
75                'kbpress %d %d 0' %
76                    (ec.KEYMATRIX[keyname][1], ec.KEYMATRIX[keyname][0]),
77                ])
78
79
80    def send_key_string_raw(self, string):
81        """Send key strokes consisting of only characters.
82
83        Args:
84          string: Raw string.
85        """
86        for c in string:
87            self.key_press(c)
88
89
90    def send_key_string(self, string):
91        """Send key strokes that can include special keys.
92
93        Args:
94          string: Character string that can include special keys. An example
95            is "this is an<tab>example<enter>".
96        """
97        for m in re.finditer("(<[^>]+>)|([^<>]+)", string):
98            sp, raw = m.groups()
99            if raw is not None:
100                self.send_key_string_raw(raw)
101            else:
102                self.key_press(sp)
103
104
105def create_base_ec(servo):
106    """Create a Base EC object.
107
108    It gets the base board name from servod and returns a ChromeBaseEC object
109    of the board.
110
111    Returns:
112      A ChromeBaseEC object, or None if not found.
113    """
114    base_board = servo.get_base_board()
115    if base_board:
116        return ChromeBaseEC(servo, base_board)
117    else:
118        logging.warn('No Base EC found on the servo board')
119        return None
120