summaryrefslogtreecommitdiff
path: root/zephyr/test/drivers/default/src/integration/usbc/usb_pd_bist_shared.c
blob: 36a417d22c239b92f4a3e8cf2d25938218388134 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/* Copyright 2022 The ChromiumOS Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "emul/emul_isl923x.h"
#include "emul/emul_smart_battery.h"
#include "emul/tcpc/emul_tcpci_partner_snk.h"
#include "test/drivers/stubs.h"
#include "test/drivers/test_state.h"
#include "test/drivers/utils.h"
#include "usb_common.h"
#include "usb_pd.h"
#include "util.h"

#include <zephyr/ztest.h>

struct usb_pd_bist_shared_fixture {
	struct tcpci_partner_data sink_5v_500ma;
	struct tcpci_snk_emul_data snk_ext_500ma;
	struct tcpci_partner_data src;
	struct tcpci_src_emul_data src_ext;
	const struct emul *tcpci_emul; /* USBC_PORT_C0 in dts */
	const struct emul *tcpci_ps8xxx_emul; /* USBC_PORT_C1 in dts */
	const struct emul *charger_emul;
};

static void *usb_pd_bist_shared_setup(void)
{
	static struct usb_pd_bist_shared_fixture test_fixture;

	/* Get references for the emulators */
	test_fixture.tcpci_emul = EMUL_GET_USBC_BINDING(0, tcpc);
	test_fixture.charger_emul = EMUL_GET_USBC_BINDING(0, chg);
	test_fixture.tcpci_ps8xxx_emul = EMUL_GET_USBC_BINDING(1, tcpc);

	return &test_fixture;
}

static void usb_pd_bist_shared_before(void *data)
{
	struct usb_pd_bist_shared_fixture *test_fixture = data;

	/* Set chipset to ON, this will set TCPM to DRP */
	test_set_chipset_to_s0();

	/* TODO(b/214401892): Check why need to give time TCPM to spin */
	k_sleep(K_SECONDS(1));

	/* Initialized the sink to request 5V and 500mA */
	tcpci_partner_init(&test_fixture->sink_5v_500ma, PD_REV30);
	test_fixture->sink_5v_500ma.extensions =
		tcpci_snk_emul_init(&test_fixture->snk_ext_500ma,
				    &test_fixture->sink_5v_500ma, NULL);
	test_fixture->snk_ext_500ma.pdo[0] = PDO_FIXED(5000, 500, 0);

	/* Initialized the source */
	tcpci_partner_init(&test_fixture->src, PD_REV30);
	test_fixture->src.extensions = tcpci_src_emul_init(
		&test_fixture->src_ext, &test_fixture->src, NULL);

	/* Initially connect the 5V 500mA partner to C0 */
	connect_sink_to_port(&test_fixture->sink_5v_500ma,
			     test_fixture->tcpci_emul,
			     test_fixture->charger_emul);
}

static void usb_pd_bist_shared_after(void *data)
{
	struct usb_pd_bist_shared_fixture *test_fixture = data;

	/* Disocnnect C0 as sink, C1 as source */
	disconnect_sink_from_port(test_fixture->tcpci_emul);
	disconnect_source_from_port(test_fixture->tcpci_ps8xxx_emul,
				    test_fixture->charger_emul);
	host_cmd_typec_control_bist_share_mode(USBC_PORT_C0, 0);
}

ZTEST_SUITE(usb_pd_bist_shared, drivers_predicate_post_main,
	    usb_pd_bist_shared_setup, usb_pd_bist_shared_before,
	    usb_pd_bist_shared_after, NULL);

ZTEST_F(usb_pd_bist_shared, verify_bist_shared_mode)
{
	uint32_t bist_data;
	uint32_t f5v_cap;

	/*
	 * Verify we were offered the 1.5A source cap because of our low current
	 * needs initially
	 */
	f5v_cap = fixture->snk_ext_500ma.last_5v_source_cap;
	/* Capability should be 5V fixed, 1.5 A */
	zassert_equal((f5v_cap & PDO_TYPE_MASK), PDO_TYPE_FIXED,
		      "PDO type wrong");
	zassert_equal(PDO_FIXED_VOLTAGE(f5v_cap), 5000, "PDO voltage wrong");
	zassert_equal(PDO_FIXED_CURRENT(f5v_cap), 1500,
		      "PDO initial current wrong");

	/* Start up BIST shared test mode */
	bist_data = BDO(BDO_MODE_SHARED_ENTER, 0);
	zassert_ok(tcpci_partner_send_data_msg(&fixture->sink_5v_500ma,
					       PD_DATA_BIST, &bist_data, 1, 0),
		   "Failed to send BIST enter message");

	/* The DUT has tBISTSharedTestMode (1 second) to offer us 3A now */
	k_sleep(K_SECONDS(1));

	f5v_cap = fixture->snk_ext_500ma.last_5v_source_cap;
	/* Capability should be 5V fixed, 3.0 A */
	zassert_equal((f5v_cap & PDO_TYPE_MASK), PDO_TYPE_FIXED,
		      "PDO type wrong");
	zassert_equal(PDO_FIXED_VOLTAGE(f5v_cap), 5000, "PDO voltage wrong");
	zassert_equal(PDO_FIXED_CURRENT(f5v_cap), 3000,
		      "PDO current didn't increase in BIST mode");

	/* Leave BIST shared test mode */
	bist_data = BDO(BDO_MODE_SHARED_EXIT, 0);
	zassert_ok(tcpci_partner_send_data_msg(&fixture->sink_5v_500ma,
					       PD_DATA_BIST, &bist_data, 1, 0),
		   "Failed to send BIST exit message");

	/*
	 * The DUT may now execute ErrorRecovery or simply send a new
	 * Source_Cap.  Either way, we should go back to 1.5 A
	 */
	k_sleep(K_SECONDS(5));

	f5v_cap = fixture->snk_ext_500ma.last_5v_source_cap;
	/* Capability should be 5V fixed, 1.5 A */
	zassert_equal((f5v_cap & PDO_TYPE_MASK), PDO_TYPE_FIXED,
		      "PDO type wrong");
	zassert_equal(PDO_FIXED_VOLTAGE(f5v_cap), 5000, "PDO voltage wrong");
	zassert_equal(PDO_FIXED_CURRENT(f5v_cap), 1500,
		      "PDO current didn't decrease after BIST exit");
}

ZTEST_F(usb_pd_bist_shared, verify_bist_shared_no_snk_entry)
{
	uint32_t bist_data;
	uint32_t f5v_cap;

	/*
	 * Ensure we only enter BIST shared mode when acting as a source.  We
	 * must not enter shared mode from PE_SNK_Ready.
	 */

	/* Attach a new source */
	connect_source_to_port(&fixture->src, &fixture->src_ext, 1,
			       fixture->tcpci_ps8xxx_emul,
			       fixture->charger_emul);

	/* Have the source send the BIST Enter Mode */
	bist_data = BDO(BDO_MODE_SHARED_ENTER, 0);
	zassert_ok(tcpci_partner_send_data_msg(&fixture->src, PD_DATA_BIST,
					       &bist_data, 1, 0),
		   "Failed to send BIST enter message");

	/* Wait tBISTSharedTestMode (1 second) */
	k_sleep(K_SECONDS(1));

	/* Verify our low power sink on C0 still only has 1.5 A */
	f5v_cap = fixture->snk_ext_500ma.last_5v_source_cap;
	/* Capability should be 5V fixed, 1.5 A */
	zassert_equal((f5v_cap & PDO_TYPE_MASK), PDO_TYPE_FIXED,
		      "PDO type wrong");
	zassert_equal(PDO_FIXED_VOLTAGE(f5v_cap), 5000, "PDO voltage wrong");
	zassert_equal(PDO_FIXED_CURRENT(f5v_cap), 1500,
		      "PDO current incorrect after bad BIST entry");
}

ZTEST_F(usb_pd_bist_shared, verify_bist_shared_exit_no_action)
{
	uint32_t bist_data;
	uint32_t f5v_cap;

	/*
	 * Verify that if we receive a BIST shared mode exit with no entry, we
	 * take no action on the port.
	 */
	tcpci_snk_emul_clear_last_5v_cap(&fixture->snk_ext_500ma);

	bist_data = BDO(BDO_MODE_SHARED_EXIT, 0);
	zassert_ok(tcpci_partner_send_data_msg(&fixture->sink_5v_500ma,
					       PD_DATA_BIST, &bist_data, 1, 0),
		   "Failed to send BIST exit message");

	/* Wait for the time it would take to settle out exit */
	k_sleep(K_SECONDS(5));

	/* Verify we didn't receive any new source caps due to the mode exit */
	f5v_cap = fixture->snk_ext_500ma.last_5v_source_cap;
	zassert_equal(f5v_cap, 0, "Received unexpected source cap");
}

ZTEST_F(usb_pd_bist_shared, verify_control_bist_shared_mode)
{
	uint32_t f5v_cap;

	host_cmd_typec_control_bist_share_mode(USBC_PORT_C0, 1);
	zassert_ok(tcpci_partner_send_control_msg(&fixture->sink_5v_500ma,
						  PD_CTRL_GET_SOURCE_CAP, 0),
		   "Failed to send get src cap");
	/* wait tSenderResponse (26 ms) */
	k_sleep(K_MSEC(26));
	/*
	 * Verify we were offered the 3A source cap because of
	 * bist share mode be enabled.
	 */
	f5v_cap = fixture->snk_ext_500ma.last_5v_source_cap;
	/* Capability should be 5V fixed, 3 A */
	zassert_equal((f5v_cap & PDO_TYPE_MASK), PDO_TYPE_FIXED,
		      "PDO type wrong");
	zassert_equal(PDO_FIXED_VOLTAGE(f5v_cap), 5000, "PDO voltage wrong");
	zassert_equal(PDO_FIXED_CURRENT(f5v_cap), 3000,
		      "PDO initial current wrong");
	zassert_equal(typec_get_default_current_limit_rp(USBC_PORT_C0),
		      TYPEC_RP_3A0, "Default rp not 3A");

	host_cmd_typec_control_bist_share_mode(USBC_PORT_C0, 0);
}