blob: 482e42b7fbe4fe4da8222782c7a38e69cec32141 [file] [log] [blame]
Rong Chang42ea8de2015-03-09 15:19:20 +08001# Copyright 2015 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
7import time
8import xmlrpclib
9
10
11class PlanktonError(Exception):
12 pass
13
14
15class Plankton(object):
16 """Manages control of a Plankton board via servod XMLRPC.
17
18 Plankton is a testing board developed to aid in USB type C debug and
19 control of various type C host devices. Plankton's features include the
20 simulation of charger, USB 2.0 pass through, USB 3.0 hub, and display port
21 pass through. This class manages setting up and communication with a servo
22 daemon (servod) process. It provides high level functions for setting and
23 reading USB type C role, mux and common controls.
24 """
25
26 DEFAULT_SERVO_HOST = 'localhost'
27 DEFAULT_SERVO_PORT = 9999
28 # USB charging command delays in seconds.
29 USBC_COMMAND_DELAY = 0.5
30 # Plankton USBC commands.
31 USBC_ROLE = 'usbc_role'
32 RE_USBC_ROLE_VOLTAGE = re.compile(r'src(\d+)v')
33 USBC_CHARGING_VOLTAGES = {
34 0: 'sink',
35 5: 'src5v',
36 12: 'src12v',
37 20: 'src20v'}
38 VBUS_VOLTAGE_MV = 'vbus_voltage'
39 VBUS_CURRENT_MA = 'vbus_current'
40 VBUS_POWER_MW = 'vbus_power'
41
42
43 def __init__(self, args_dict=None):
44 """Sets up servo daemon communication.
45
46 @param args_dict: A dictionary contains plankton servod host and port.
47 Example: {'plankton_host': 'localhost',
48 'plankton_port': 9999}
49 """
50 if args_dict is None:
51 args_dict = {}
52 plankton_host = args_dict.get('plankton_host', self.DEFAULT_SERVO_HOST)
53 plankton_port = args_dict.get('plankton_port', self.DEFAULT_SERVO_PORT)
54 remote = 'http://%s:%s' % (plankton_host, plankton_port)
55 self._server = xmlrpclib.ServerProxy(remote)
Johny Lin1f255912015-03-12 12:38:11 +080056 self.init_io_expander()
57
58
59 def init_io_expander(self):
60 """Initializes Plankton IO expander register settings."""
61 if not int(self.get('debug_usb_sel')):
62 raise PlanktonError('debug_usb_sel (SW3) should be ON!! '
63 'Please use CN15 to connect Plankton.')
64 self.set('typec_to_hub_sw', '0')
65 self.set('usb2_mux_sw', '1')
66 self.set('usb_dn_pwren', 'on')
Rong Chang42ea8de2015-03-09 15:19:20 +080067
68
69 def set(self, control_name, value):
70 """Sets the value of a control using servod."""
71 assert control_name
72 self._server.set(control_name, value)
73
74
75 def get(self, control_name):
76 """Gets the value of a control from servod."""
77 assert control_name
78 return self._server.get(control_name)
79
80
81 @property
82 def vbus_voltage(self):
83 """Gets Plankton VBUS voltage in volts."""
84 return float(self.get(self.VBUS_VOLTAGE_MV)) / 1000.0
85
86
87 @property
88 def vbus_current(self):
89 """Gets Plankton VBUS current in amps."""
90 return float(self.get(self.VBUS_CURRENT_MA)) / 1000.0
91
92
93 @property
94 def vbus_power(self):
95 """Gets Plankton charging power in watts."""
96 return float(self.get(self.VBUS_POWER_MW)) / 1000.0
97
98
99 def get_charging_voltages(self):
100 """Gets the lists of available charging voltages."""
101 return self.USBC_CHARGING_VOLTAGES.keys()
102
103
104 def charge(self, voltage):
105 """Sets Plankton to provide power at specific voltage.
106
107 @param voltage: Specified charging voltage in volts.
108 """
109 if voltage not in self.USBC_CHARGING_VOLTAGES:
110 raise PlanktonError('Invalid charging voltage: %s' % voltage)
111
112 self.set(self.USBC_ROLE, self.USBC_CHARGING_VOLTAGES[voltage])
113 time.sleep(self.USBC_COMMAND_DELAY)
114
115
116 @property
117 def charging_voltage(self):
118 """Gets current charging voltage."""
119 usbc_role = self.get(self.USBC_ROLE)
120 match = self.RE_USBC_ROLE_VOLTAGE(usbc_role)
121 if match:
122 return int(match.group(1))
123
124 if usbc_role == self.USBC_CHARGING_VOLTAGES[0]:
125 return 0
126
127 raise PlanktonError('Invalid USBC role: %s' % usbc_role)