Update the result callback routine to also provide information about the charging mode role. This permits tests to validate plug/unplug events detected by the BC1.2 device operating in charging mode. Signed-off-by: Keith Short <keithshort@google.com>
205 lines
6.3 KiB
C
205 lines
6.3 KiB
C
/*
|
|
* Copyright 2022 Google LLC
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
/**
|
|
* @defgroup driver_bc12_tests
|
|
* @ingroup all_tests
|
|
* @{
|
|
* @defgroup t_bc12_portable_device
|
|
* @brief TestPurpose: Verify BC1.2 devices in portable device mode.
|
|
* @}
|
|
*/
|
|
|
|
#include <zephyr/drivers/usb/usb_bc12.h>
|
|
#include <zephyr/drivers/usb/emul_bc12.h>
|
|
#include <zephyr/ztest.h>
|
|
|
|
#include <zephyr/logging/log.h>
|
|
|
|
#define LOG_MODULE_NAME test_bc12_pd_mode
|
|
LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_INF);
|
|
|
|
struct bc12_pd_mode_fixture {
|
|
const struct device *bc12_dev;
|
|
const struct emul *bc12_emul;
|
|
int callback_count;
|
|
bool disconnect_detected;
|
|
struct bc12_partner_state partner_state;
|
|
};
|
|
|
|
static void bc12_test_result_cb(const struct device *dev, struct bc12_partner_state *state,
|
|
void *user_data)
|
|
{
|
|
struct bc12_pd_mode_fixture *fixture = user_data;
|
|
|
|
fixture->callback_count++;
|
|
|
|
if (state) {
|
|
if (state->bc12_role == BC12_PORTABLE_DEVICE) {
|
|
LOG_INF("charging partner: type %d, voltage %d, current %d", state->type,
|
|
state->voltage_uv, state->current_ua);
|
|
} else if (state->bc12_role == BC12_CHARGING_PORT) {
|
|
LOG_INF("portable device partner: connected %d",
|
|
state->pd_partner_connected);
|
|
}
|
|
fixture->partner_state = *state;
|
|
} else {
|
|
LOG_INF("callback: partner disconnect");
|
|
fixture->disconnect_detected = true;
|
|
fixture->partner_state.type = BC12_TYPE_NONE;
|
|
fixture->partner_state.current_ua = 0;
|
|
fixture->partner_state.voltage_uv = 0;
|
|
}
|
|
}
|
|
|
|
ZTEST_USER_F(bc12_pd_mode, test_bc12_no_charging_partner)
|
|
{
|
|
bc12_emul_set_charging_partner(fixture->bc12_emul, BC12_TYPE_NONE);
|
|
|
|
bc12_set_role(fixture->bc12_dev, BC12_PORTABLE_DEVICE);
|
|
|
|
k_sleep(K_MSEC(100));
|
|
|
|
/* Without any device connected, our callback should not execute */
|
|
zassert_equal(fixture->callback_count, 0);
|
|
}
|
|
|
|
ZTEST_USER_F(bc12_pd_mode, test_bc12_sdp_charging_partner)
|
|
{
|
|
/* Connect a SDP charging partner to the emulator */
|
|
bc12_emul_set_charging_partner(fixture->bc12_emul, BC12_TYPE_SDP);
|
|
|
|
/* Report to the BC1.2 driver that VBUS is present */
|
|
bc12_set_role(fixture->bc12_dev, BC12_PORTABLE_DEVICE);
|
|
|
|
k_sleep(K_MSEC(100));
|
|
|
|
/*
|
|
* Note that in SDP mode, the USB device is limited to 2.5 mA until
|
|
* the USB bus is not suspended or the USB device configured.
|
|
*
|
|
* The BC1.2 driver contract specifies to set the current to Isusp
|
|
* for SDP ports or when BC1.2 detection fails.
|
|
*/
|
|
zassert_equal(fixture->callback_count, 1);
|
|
zassert_equal(fixture->partner_state.bc12_role, BC12_PORTABLE_DEVICE);
|
|
zassert_equal(fixture->partner_state.type, BC12_TYPE_SDP);
|
|
zassert_equal(fixture->partner_state.current_ua, 2500);
|
|
zassert_equal(fixture->partner_state.voltage_uv, 5000 * 1000);
|
|
|
|
/* Remove the charging partner */
|
|
fixture->callback_count = 0;
|
|
bc12_emul_set_charging_partner(fixture->bc12_emul, BC12_TYPE_NONE);
|
|
|
|
/* Report to the BC1.2 driver that VBUS is no longer present */
|
|
bc12_set_role(fixture->bc12_dev, BC12_DISCONNECTED);
|
|
|
|
k_sleep(K_MSEC(100));
|
|
|
|
/* The BC1.2 driver should invoke the callback on disconnects */
|
|
zassert_equal(fixture->callback_count, 1);
|
|
zassert_equal(fixture->partner_state.type, BC12_TYPE_NONE);
|
|
zassert_equal(fixture->partner_state.current_ua, 0);
|
|
zassert_equal(fixture->partner_state.voltage_uv, 0);
|
|
}
|
|
|
|
ZTEST_USER_F(bc12_pd_mode, test_bc12_cdp_charging_partner)
|
|
{
|
|
bc12_emul_set_charging_partner(fixture->bc12_emul, BC12_TYPE_CDP);
|
|
|
|
bc12_set_role(fixture->bc12_dev, BC12_PORTABLE_DEVICE);
|
|
|
|
k_sleep(K_MSEC(100));
|
|
|
|
zassert_equal(fixture->callback_count, 1);
|
|
zassert_equal(fixture->partner_state.bc12_role, BC12_PORTABLE_DEVICE);
|
|
zassert_equal(fixture->partner_state.type, BC12_TYPE_CDP);
|
|
zassert_equal(fixture->partner_state.current_ua, 1500 * 1000);
|
|
zassert_equal(fixture->partner_state.voltage_uv, 5000 * 1000);
|
|
|
|
/* Remove the charging partner */
|
|
fixture->callback_count = 0;
|
|
bc12_emul_set_charging_partner(fixture->bc12_emul, BC12_TYPE_NONE);
|
|
|
|
/* Report to the BC1.2 driver that VBUS is no longer present */
|
|
bc12_set_role(fixture->bc12_dev, BC12_DISCONNECTED);
|
|
|
|
k_sleep(K_MSEC(100));
|
|
|
|
/* The BC1.2 driver should invoke the callback on disconnects */
|
|
zassert_equal(fixture->callback_count, 1);
|
|
zassert_true(fixture->disconnect_detected);
|
|
zassert_equal(fixture->partner_state.type, BC12_TYPE_NONE);
|
|
zassert_equal(fixture->partner_state.current_ua, 0);
|
|
zassert_equal(fixture->partner_state.voltage_uv, 0);
|
|
}
|
|
|
|
ZTEST_USER_F(bc12_pd_mode, test_bc12_sdp_to_dcp_charging_partner)
|
|
{
|
|
bc12_emul_set_charging_partner(fixture->bc12_emul, BC12_TYPE_SDP);
|
|
|
|
bc12_set_role(fixture->bc12_dev, BC12_PORTABLE_DEVICE);
|
|
|
|
k_sleep(K_MSEC(100));
|
|
|
|
zassert_equal(fixture->callback_count, 1);
|
|
zassert_equal(fixture->partner_state.bc12_role, BC12_PORTABLE_DEVICE);
|
|
zassert_equal(fixture->partner_state.type, BC12_TYPE_SDP);
|
|
zassert_equal(fixture->partner_state.current_ua, 2500);
|
|
zassert_equal(fixture->partner_state.voltage_uv, 5000 * 1000);
|
|
|
|
/* Change the partner type to DCP */
|
|
fixture->callback_count = 0;
|
|
bc12_emul_set_charging_partner(fixture->bc12_emul, BC12_TYPE_DCP);
|
|
|
|
/* Trigger a new detection */
|
|
bc12_set_role(fixture->bc12_dev, BC12_PORTABLE_DEVICE);
|
|
|
|
k_sleep(K_MSEC(100));
|
|
|
|
/* The BC1.2 driver should invoke the callback once to report the new state. */
|
|
zassert_equal(fixture->callback_count, 1);
|
|
zassert_equal(fixture->partner_state.bc12_role, BC12_PORTABLE_DEVICE);
|
|
zassert_equal(fixture->partner_state.type, BC12_TYPE_DCP);
|
|
zassert_equal(fixture->partner_state.current_ua, 1500 * 1000);
|
|
zassert_equal(fixture->partner_state.voltage_uv, 5000 * 1000);
|
|
}
|
|
|
|
static void bc12_before(void *data)
|
|
{
|
|
struct bc12_pd_mode_fixture *fixture = data;
|
|
|
|
fixture->callback_count = 0;
|
|
fixture->disconnect_detected = 0;
|
|
memset(&fixture->partner_state, 0, sizeof(struct bc12_partner_state));
|
|
|
|
bc12_set_result_cb(fixture->bc12_dev, &bc12_test_result_cb, fixture);
|
|
}
|
|
|
|
static void bc12_after(void *data)
|
|
{
|
|
struct bc12_pd_mode_fixture *fixture = data;
|
|
|
|
bc12_set_result_cb(fixture->bc12_dev, NULL, NULL);
|
|
bc12_set_role(fixture->bc12_dev, BC12_DISCONNECTED);
|
|
}
|
|
|
|
static void *bc12_setup(void)
|
|
{
|
|
static struct bc12_pd_mode_fixture fixture = {
|
|
.bc12_dev = DEVICE_DT_GET(DT_ALIAS(bc12)),
|
|
.bc12_emul = EMUL_DT_GET(DT_ALIAS(bc12)),
|
|
};
|
|
|
|
zassert_not_null(fixture.bc12_dev);
|
|
zassert_not_null(fixture.bc12_emul);
|
|
zassert_true(device_is_ready(fixture.bc12_dev));
|
|
|
|
return &fixture;
|
|
}
|
|
|
|
ZTEST_SUITE(bc12_pd_mode, NULL, bc12_setup, bc12_before, bc12_after, NULL);
|