summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Michalec <tm@semihalf.com>2021-12-28 17:07:14 +0100
committerCommit Bot <commit-bot@chromium.org>2022-01-14 23:07:23 +0000
commit6d4f386d19670dffc15b6d145e1f475d1ce6dc80 (patch)
treee0e91293d504f1b0af35cc3f1c3df1683837add6
parent5fff14e36783d872151c72a113d6a2261778a373 (diff)
downloadchrome-ec-6d4f386d19670dffc15b6d145e1f475d1ce6dc80.tar.gz
zephyr: emul: Separate data and partner emulator
Separate data of sink and source TCPCI partner emulators from TCPCI partner emulator itself. It is possible to use data of basic partner emulators as components of more complicated partner emulator. BUG=none BRANCH=none TEST=make configure --test zephyr/test/drivers Signed-off-by: Tomasz Michalec <tm@semihalf.com> Change-Id: Iaa1c4535f781c1daa68d365a448bbca5bed3bdbc Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3358578 Reviewed-by: Abe Levkoy <alevkoy@chromium.org> Tested-by: Tomasz Michalec <tmichalec@google.com> Commit-Queue: Tomasz Michalec <tmichalec@google.com>
-rw-r--r--zephyr/emul/tcpc/emul_tcpci.c4
-rw-r--r--zephyr/emul/tcpc/emul_tcpci_partner_snk.c183
-rw-r--r--zephyr/emul/tcpc/emul_tcpci_partner_src.c175
-rw-r--r--zephyr/include/emul/tcpc/emul_tcpci.h2
-rw-r--r--zephyr/include/emul/tcpc/emul_tcpci_partner_snk.h53
-rw-r--r--zephyr/include/emul/tcpc/emul_tcpci_partner_src.h63
-rw-r--r--zephyr/test/drivers/src/integration_usb.c20
7 files changed, 313 insertions, 187 deletions
diff --git a/zephyr/emul/tcpc/emul_tcpci.c b/zephyr/emul/tcpc/emul_tcpci.c
index 18249bed55..4a33a48f59 100644
--- a/zephyr/emul/tcpc/emul_tcpci.c
+++ b/zephyr/emul/tcpc/emul_tcpci.c
@@ -58,7 +58,7 @@ struct tcpci_emul_data {
/** Callbacks for specific TCPCI device emulator */
struct tcpci_emul_dev_ops *dev_ops;
/** Callbacks for TCPCI partner */
- struct tcpci_emul_partner_ops *partner;
+ const struct tcpci_emul_partner_ops *partner;
/** Reference to Alert# GPIO emulator. */
const struct device *alert_gpio_port;
@@ -351,7 +351,7 @@ void tcpci_emul_set_alert_callback(const struct emul *emul,
/** Check description in emul_tcpci.h */
void tcpci_emul_set_partner_ops(const struct emul *emul,
- struct tcpci_emul_partner_ops *partner)
+ const struct tcpci_emul_partner_ops *partner)
{
struct tcpci_emul_data *data = emul->data;
diff --git a/zephyr/emul/tcpc/emul_tcpci_partner_snk.c b/zephyr/emul/tcpc/emul_tcpci_partner_snk.c
index cfeb11b7dd..b87bc37ed3 100644
--- a/zephyr/emul/tcpc/emul_tcpci_partner_snk.c
+++ b/zephyr/emul/tcpc/emul_tcpci_partner_snk.c
@@ -42,21 +42,24 @@ static int tcpci_snk_emul_num_of_pdos(struct tcpci_snk_emul_data *data)
* @brief Send capability message constructed from USB-C sink emulator PDOs
*
* @param data Pointer to USB-C sink emulator
+ * @param common_data Pointer to common TCPCI partner data
* @param delay Optional delay
*
* @return 0 on success
* @return -ENOMEM when there is no free memory for message
* @return -EINVAL on TCPCI emulator add RX message error
*/
-static int tcpci_snk_emul_send_capability_msg(struct tcpci_snk_emul_data *data,
- uint64_t delay)
+static int tcpci_snk_emul_send_capability_msg(
+ struct tcpci_snk_emul_data *data,
+ struct tcpci_partner_data *common_data,
+ uint64_t delay)
{
int pdos;
/* Find number of PDOs */
pdos = tcpci_snk_emul_num_of_pdos(data);
- return tcpci_partner_send_data_msg(&data->common_data,
+ return tcpci_partner_send_data_msg(common_data,
PD_DATA_SINK_CAP,
data->pdo, pdos, delay);
}
@@ -232,10 +235,13 @@ static uint32_t tcpci_snk_emul_create_rdo(uint32_t src_pdo, uint32_t snk_pdo,
* @brief Respond to source capability message
*
* @param data Pointer to USB-C sink emulator
+ * @param common_data Pointer to common TCPCI partner data
* @param msg Source capability message
*/
-static void tcpci_snk_emul_handle_source_cap(struct tcpci_snk_emul_data *data,
- const struct tcpci_emul_msg *msg)
+static void tcpci_snk_emul_handle_source_cap(
+ struct tcpci_snk_emul_data *data,
+ struct tcpci_partner_data *common_data,
+ const struct tcpci_emul_msg *msg)
{
uint32_t rdo = 0;
uint32_t pdo;
@@ -283,11 +289,65 @@ static void tcpci_snk_emul_handle_source_cap(struct tcpci_snk_emul_data *data,
}
/* Expect response for request */
- data->common_data.wait_for_response = true;
- tcpci_partner_send_data_msg(&data->common_data, PD_DATA_REQUEST, &rdo,
+ common_data->wait_for_response = true;
+ tcpci_partner_send_data_msg(common_data, PD_DATA_REQUEST, &rdo,
1 /* = data_obj_num */, 0 /* = delay */);
}
+/** Check description in emul_tcpci_snk.h */
+enum tcpci_partner_handler_res tcpci_snk_emul_handle_sop_msg(
+ struct tcpci_snk_emul_data *data,
+ struct tcpci_partner_data *common_data,
+ const struct tcpci_emul_msg *msg)
+{
+ uint16_t header;
+
+ header = sys_get_le16(msg->buf);
+
+ if (PD_HEADER_CNT(header)) {
+ /* Handle data message */
+ switch (PD_HEADER_TYPE(header)) {
+ case PD_DATA_SOURCE_CAP:
+ tcpci_snk_emul_handle_source_cap(data, common_data,
+ msg);
+ return TCPCI_PARTNER_COMMON_MSG_HANDLED;
+ default:
+ return TCPCI_PARTNER_COMMON_MSG_NOT_HANDLED;
+ }
+ } else {
+ /* Handle control message */
+ switch (PD_HEADER_TYPE(header)) {
+ case PD_CTRL_GET_SINK_CAP:
+ tcpci_snk_emul_send_capability_msg(data, common_data,
+ 0);
+ return TCPCI_PARTNER_COMMON_MSG_HANDLED;
+ case PD_CTRL_PING:
+ return TCPCI_PARTNER_COMMON_MSG_HANDLED;
+ case PD_CTRL_PS_RDY:
+ __ASSERT(data->wait_for_ps_rdy,
+ "Unexpected PS RDY message");
+ data->wait_for_ps_rdy = false;
+ data->pd_completed = true;
+ return TCPCI_PARTNER_COMMON_MSG_HANDLED;
+ case PD_CTRL_REJECT:
+ /* Request rejected. Ask for capabilities again. */
+ tcpci_partner_send_control_msg(common_data,
+ PD_CTRL_GET_SOURCE_CAP,
+ 0);
+ common_data->wait_for_response = false;
+ return TCPCI_PARTNER_COMMON_MSG_HANDLED;
+ case PD_CTRL_ACCEPT:
+ common_data->wait_for_response = false;
+ data->wait_for_ps_rdy = true;
+ return TCPCI_PARTNER_COMMON_MSG_HANDLED;
+ default:
+ return TCPCI_PARTNER_COMMON_MSG_NOT_HANDLED;
+ }
+ }
+
+ return TCPCI_PARTNER_COMMON_MSG_NOT_HANDLED;
+}
+
/**
* @brief Function called when TCPM wants to transmit message. Accept received
* message and generate response.
@@ -304,19 +364,19 @@ static void tcpci_snk_emul_transmit_op(const struct emul *emul,
enum tcpci_msg_type type,
int retry)
{
- struct tcpci_snk_emul_data *data =
- CONTAINER_OF(ops, struct tcpci_snk_emul_data, ops);
+ struct tcpci_snk_emul *snk_emul =
+ CONTAINER_OF(ops, struct tcpci_snk_emul, ops);
enum tcpci_partner_handler_res processed;
- uint16_t header;
- processed = tcpci_partner_common_msg_handler(&data->common_data,
+ /* Call common handler */
+ processed = tcpci_partner_common_msg_handler(&snk_emul->common_data,
tx_msg, type,
TCPCI_EMUL_TX_SUCCESS);
switch (processed) {
case TCPCI_PARTNER_COMMON_MSG_HARD_RESET:
/* Handle hard reset */
- data->wait_for_ps_rdy = false;
- data->pd_completed = false;
+ snk_emul->data.wait_for_ps_rdy = false;
+ snk_emul->data.pd_completed = false;
return;
case TCPCI_PARTNER_COMMON_MSG_HANDLED:
@@ -333,57 +393,14 @@ static void tcpci_snk_emul_transmit_op(const struct emul *emul,
return;
}
- header = sys_get_le16(tx_msg->buf);
-
- if (PD_HEADER_CNT(header)) {
- /* Handle data message */
- switch (PD_HEADER_TYPE(header)) {
- case PD_DATA_SOURCE_CAP:
- tcpci_snk_emul_handle_source_cap(data, tx_msg);
- break;
- default:
- tcpci_partner_send_control_msg(&data->common_data,
- PD_CTRL_REJECT, 0);
- break;
- }
- } else {
- /* Handle control message */
- switch (PD_HEADER_TYPE(header)) {
- case PD_CTRL_GET_SOURCE_CAP:
- tcpci_partner_send_control_msg(&data->common_data,
- PD_CTRL_REJECT, 0);
- break;
- case PD_CTRL_GET_SINK_CAP:
- tcpci_snk_emul_send_capability_msg(data, 0);
- break;
- case PD_CTRL_DR_SWAP:
- tcpci_partner_send_control_msg(&data->common_data,
- PD_CTRL_REJECT, 0);
- break;
- case PD_CTRL_PING:
- break;
- case PD_CTRL_PS_RDY:
- __ASSERT(data->wait_for_ps_rdy,
- "Unexpected PS RDY message");
- data->wait_for_ps_rdy = false;
- data->pd_completed = true;
- break;
- case PD_CTRL_REJECT:
- /* Request rejected. Ask for capabilities again. */
- tcpci_partner_send_control_msg(&data->common_data,
- PD_CTRL_GET_SOURCE_CAP,
- 0);
- data->common_data.wait_for_response = false;
- break;
- case PD_CTRL_ACCEPT:
- data->common_data.wait_for_response = false;
- data->wait_for_ps_rdy = true;
- break;
- default:
- tcpci_partner_send_control_msg(&data->common_data,
- PD_CTRL_REJECT, 0);
- break;
- }
+ /* Call sink specific handler */
+ processed = tcpci_snk_emul_handle_sop_msg(&snk_emul->data,
+ &snk_emul->common_data,
+ tx_msg);
+ if (processed == TCPCI_PARTNER_COMMON_MSG_NOT_HANDLED) {
+ /* Send reject for not handled messages (PD rev 2.0) */
+ tcpci_partner_send_control_msg(&snk_emul->common_data,
+ PD_CTRL_REJECT, 0);
}
}
@@ -409,16 +426,18 @@ static void tcpci_snk_emul_rx_consumed_op(
/** Check description in emul_tcpci_snk.h */
int tcpci_snk_emul_connect_to_tcpci(struct tcpci_snk_emul_data *data,
+ struct tcpci_partner_data *common_data,
+ const struct tcpci_emul_partner_ops *ops,
const struct emul *tcpci_emul)
{
int ret;
- tcpci_emul_set_partner_ops(tcpci_emul, &data->ops);
+ tcpci_emul_set_partner_ops(tcpci_emul, ops);
ret = tcpci_emul_connect_partner(tcpci_emul, PD_ROLE_SINK,
TYPEC_CC_VOLT_RD,
TYPEC_CC_VOLT_OPEN, POLARITY_CC1);
if (!ret) {
- data->common_data.tcpci_emul = tcpci_emul;
+ common_data->tcpci_emul = tcpci_emul;
}
data->wait_for_ps_rdy = false;
@@ -428,21 +447,31 @@ int tcpci_snk_emul_connect_to_tcpci(struct tcpci_snk_emul_data *data,
}
/** Check description in emul_tcpci_snk.h */
-void tcpci_snk_emul_init(struct tcpci_snk_emul_data *data)
+void tcpci_snk_emul_init_data(struct tcpci_snk_emul_data *data)
{
- tcpci_partner_init(&data->common_data);
-
- data->common_data.data_role = PD_ROLE_DFP;
- data->common_data.power_role = PD_ROLE_SINK;
- data->common_data.rev = PD_REV20;
-
- data->ops.transmit = tcpci_snk_emul_transmit_op;
- data->ops.rx_consumed = tcpci_snk_emul_rx_consumed_op;
- data->ops.control_change = NULL;
-
/* By default there is only PDO 5v@500mA */
data->pdo[0] = PDO_FIXED(5000, 500, 0);
for (int i = 1; i < PDO_MAX_OBJECTS; i++) {
data->pdo[i] = 0;
}
+
+ data->wait_for_ps_rdy = false;
+ data->pd_completed = false;
+
+}
+
+/** Check description in emul_tcpci_snk.h */
+void tcpci_snk_emul_init(struct tcpci_snk_emul *emul)
+{
+ tcpci_partner_init(&emul->common_data);
+
+ emul->common_data.data_role = PD_ROLE_DFP;
+ emul->common_data.power_role = PD_ROLE_SINK;
+ emul->common_data.rev = PD_REV20;
+
+ emul->ops.transmit = tcpci_snk_emul_transmit_op;
+ emul->ops.rx_consumed = tcpci_snk_emul_rx_consumed_op;
+ emul->ops.control_change = NULL;
+
+ tcpci_snk_emul_init_data(&emul->data);
}
diff --git a/zephyr/emul/tcpc/emul_tcpci_partner_src.c b/zephyr/emul/tcpc/emul_tcpci_partner_src.c
index 11cc5e4033..263548190a 100644
--- a/zephyr/emul/tcpc/emul_tcpci_partner_src.c
+++ b/zephyr/emul/tcpc/emul_tcpci_partner_src.c
@@ -15,18 +15,10 @@ LOG_MODULE_REGISTER(tcpci_src_emul, CONFIG_TCPCI_EMUL_LOG_LEVEL);
#include "emul/tcpc/emul_tcpci.h"
#include "usb_pd.h"
-/**
- * @brief Send capability message constructed from source device emulator PDOs
- *
- * @param data Pointer to USB-C source device emulator
- * @param delay Optional delay
- *
- * @return 0 on success
- * @return -ENOMEM when there is no free memory for message
- * @return -EINVAL on TCPCI emulator add RX message error
- */
-static int tcpci_src_emul_send_capability_msg(struct tcpci_src_emul_data *data,
- uint64_t delay)
+/** Check description in emul_tcpci_partner_src.h */
+int tcpci_src_emul_send_capability_msg(struct tcpci_src_emul_data *data,
+ struct tcpci_partner_data *common_data,
+ uint64_t delay)
{
int pdos;
@@ -37,11 +29,52 @@ static int tcpci_src_emul_send_capability_msg(struct tcpci_src_emul_data *data,
}
}
- return tcpci_partner_send_data_msg(&data->common_data,
+ return tcpci_partner_send_data_msg(common_data,
PD_DATA_SOURCE_CAP,
data->pdo, pdos, delay);
}
+/** Check description in emul_tcpci_partner_src.h */
+enum tcpci_partner_handler_res tcpci_src_emul_handle_sop_msg(
+ struct tcpci_src_emul_data *data,
+ struct tcpci_partner_data *common_data,
+ const struct tcpci_emul_msg *msg)
+{
+ uint16_t header;
+
+ header = sys_get_le16(msg->buf);
+
+ if (PD_HEADER_CNT(header)) {
+ /* Handle data message */
+ switch (PD_HEADER_TYPE(header)) {
+ case PD_DATA_REQUEST:
+ tcpci_partner_send_control_msg(common_data,
+ PD_CTRL_ACCEPT, 0);
+ /* PS ready after 15 ms */
+ tcpci_partner_send_control_msg(common_data,
+ PD_CTRL_PS_RDY, 15);
+ return TCPCI_PARTNER_COMMON_MSG_HANDLED;
+ default:
+ return TCPCI_PARTNER_COMMON_MSG_NOT_HANDLED;
+ }
+ } else {
+ /* Handle control message */
+ switch (PD_HEADER_TYPE(header)) {
+ case PD_CTRL_GET_SOURCE_CAP:
+ tcpci_src_emul_send_capability_msg(data, common_data,
+ 0);
+ return TCPCI_PARTNER_COMMON_MSG_HANDLED;
+ case PD_CTRL_SOFT_RESET:
+ /* Send capability after 15 ms to establish PD again */
+ tcpci_src_emul_send_capability_msg(data, common_data,
+ 15);
+ return TCPCI_PARTNER_COMMON_MSG_HANDLED;
+ default:
+ return TCPCI_PARTNER_COMMON_MSG_NOT_HANDLED;
+ }
+ }
+}
+
/**
* @brief Function called when TCPM wants to transmit message. Accept received
* message and generate response.
@@ -58,18 +91,19 @@ static void tcpci_src_emul_transmit_op(const struct emul *emul,
enum tcpci_msg_type type,
int retry)
{
- struct tcpci_src_emul_data *data =
- CONTAINER_OF(ops, struct tcpci_src_emul_data, ops);
+ struct tcpci_src_emul *src_emul =
+ CONTAINER_OF(ops, struct tcpci_src_emul, ops);
enum tcpci_partner_handler_res processed;
uint16_t header;
- processed = tcpci_partner_common_msg_handler(&data->common_data,
+ processed = tcpci_partner_common_msg_handler(&src_emul->common_data,
tx_msg, type,
TCPCI_EMUL_TX_SUCCESS);
/* Handle hard reset */
if (processed == TCPCI_PARTNER_COMMON_MSG_HARD_RESET) {
/* Send capability after 15 ms to establish PD again */
- tcpci_src_emul_send_capability_msg(data, 15);
+ tcpci_src_emul_send_capability_msg(&src_emul->data,
+ &src_emul->common_data, 15);
return;
}
@@ -80,59 +114,24 @@ static void tcpci_src_emul_transmit_op(const struct emul *emul,
}
header = sys_get_le16(tx_msg->buf);
+ if (processed == TCPCI_PARTNER_COMMON_MSG_HANDLED &&
+ !(PD_HEADER_CNT(header) == 0 &&
+ PD_HEADER_TYPE(header) == PD_CTRL_SOFT_RESET)) {
+ /*
+ * Only soft reset requires additional handling after
+ * common handler
+ */
+ return;
+ }
- if (PD_HEADER_CNT(header)) {
- if (processed == TCPCI_PARTNER_COMMON_MSG_HANDLED) {
- /* Message already processed by common handler */
- return;
- }
-
- /* Handle data message */
- switch (PD_HEADER_TYPE(header)) {
- case PD_DATA_REQUEST:
- tcpci_partner_send_control_msg(&data->common_data,
- PD_CTRL_ACCEPT, 0);
- /* PS ready after 15 ms */
- tcpci_partner_send_control_msg(&data->common_data,
- PD_CTRL_PS_RDY, 15);
- break;
- default:
- tcpci_partner_send_control_msg(&data->common_data,
- PD_CTRL_REJECT, 0);
- break;
- }
- } else {
- if (processed == TCPCI_PARTNER_COMMON_MSG_HANDLED &&
- PD_HEADER_TYPE(header) != PD_CTRL_SOFT_RESET) {
- /*
- * Only soft reset requires additional handling after
- * common handler
- */
- return;
- }
-
- /* Handle control message */
- switch (PD_HEADER_TYPE(header)) {
- case PD_CTRL_GET_SOURCE_CAP:
- tcpci_src_emul_send_capability_msg(data, 0);
- break;
- case PD_CTRL_GET_SINK_CAP:
- tcpci_partner_send_control_msg(&data->common_data,
- PD_CTRL_REJECT, 0);
- break;
- case PD_CTRL_DR_SWAP:
- tcpci_partner_send_control_msg(&data->common_data,
- PD_CTRL_REJECT, 0);
- break;
- case PD_CTRL_SOFT_RESET:
- /* Send capability after 15 ms to establish PD again */
- tcpci_src_emul_send_capability_msg(data, 15);
- break;
- default:
- tcpci_partner_send_control_msg(&data->common_data,
- PD_CTRL_REJECT, 0);
- break;
- }
+ /* Call source specific handler */
+ processed = tcpci_src_emul_handle_sop_msg(&src_emul->data,
+ &src_emul->common_data,
+ tx_msg);
+ if (processed == TCPCI_PARTNER_COMMON_MSG_NOT_HANDLED) {
+ /* Send reject for not handled messages (PD rev 2.0) */
+ tcpci_partner_send_control_msg(&src_emul->common_data,
+ PD_CTRL_REJECT, 0);
}
}
@@ -158,11 +157,13 @@ static void tcpci_src_emul_rx_consumed_op(
/** Check description in emul_tcpci_partner_src.h */
int tcpci_src_emul_connect_to_tcpci(struct tcpci_src_emul_data *data,
+ struct tcpci_partner_data *common_data,
+ const struct tcpci_emul_partner_ops *ops,
const struct emul *tcpci_emul)
{
int ec;
- tcpci_emul_set_partner_ops(tcpci_emul, &data->ops);
+ tcpci_emul_set_partner_ops(tcpci_emul, ops);
ec = tcpci_emul_connect_partner(tcpci_emul, PD_ROLE_SOURCE,
TYPEC_CC_VOLT_RP_3_0,
TYPEC_CC_VOLT_OPEN, POLARITY_CC1);
@@ -170,9 +171,9 @@ int tcpci_src_emul_connect_to_tcpci(struct tcpci_src_emul_data *data,
return ec;
}
- data->common_data.tcpci_emul = tcpci_emul;
+ common_data->tcpci_emul = tcpci_emul;
- return tcpci_src_emul_send_capability_msg(data, 0);
+ return tcpci_src_emul_send_capability_msg(data, common_data, 0);
}
#define PDO_FIXED_FLAGS_MASK \
@@ -274,22 +275,28 @@ enum check_pdos_res tcpci_src_emul_check_pdos(struct tcpci_src_emul_data *data)
return TCPCI_SRC_EMUL_CHECK_PDO_OK;
}
-/** Check description in emul_tcpci_parnter_src.h */
-void tcpci_src_emul_init(struct tcpci_src_emul_data *data)
+/** Check description in emul_tcpci_partner_src.h */
+void tcpci_src_emul_init_data(struct tcpci_src_emul_data *data)
{
- tcpci_partner_init(&data->common_data);
-
- data->common_data.data_role = PD_ROLE_UFP;
- data->common_data.power_role = PD_ROLE_SOURCE;
- data->common_data.rev = PD_REV20;
-
- data->ops.transmit = tcpci_src_emul_transmit_op;
- data->ops.rx_consumed = tcpci_src_emul_rx_consumed_op;
- data->ops.control_change = NULL;
-
/* By default there is only PDO 5v@3A */
data->pdo[0] = PDO_FIXED(5000, 3000, PDO_FIXED_UNCONSTRAINED);
for (int i = 1; i < PDO_MAX_OBJECTS; i++) {
data->pdo[i] = 0;
}
}
+
+/** Check description in emul_tcpci_parnter_src.h */
+void tcpci_src_emul_init(struct tcpci_src_emul *emul)
+{
+ tcpci_partner_init(&emul->common_data);
+
+ emul->common_data.data_role = PD_ROLE_UFP;
+ emul->common_data.power_role = PD_ROLE_SOURCE;
+ emul->common_data.rev = PD_REV20;
+
+ emul->ops.transmit = tcpci_src_emul_transmit_op;
+ emul->ops.rx_consumed = tcpci_src_emul_rx_consumed_op;
+ emul->ops.control_change = NULL;
+
+ tcpci_src_emul_init_data(&emul->data);
+}
diff --git a/zephyr/include/emul/tcpc/emul_tcpci.h b/zephyr/include/emul/tcpc/emul_tcpci.h
index 3a5a3047d7..22a5e243a4 100644
--- a/zephyr/include/emul/tcpc/emul_tcpci.h
+++ b/zephyr/include/emul/tcpc/emul_tcpci.h
@@ -276,7 +276,7 @@ void tcpci_emul_set_alert_callback(const struct emul *emul,
* @param partner Pointer to callbacks
*/
void tcpci_emul_set_partner_ops(const struct emul *emul,
- struct tcpci_emul_partner_ops *partner);
+ const struct tcpci_emul_partner_ops *partner);
/**
* @brief Emulate connection of specific device to emulated TCPCI
diff --git a/zephyr/include/emul/tcpc/emul_tcpci_partner_snk.h b/zephyr/include/emul/tcpc/emul_tcpci_partner_snk.h
index f094705799..8948243969 100644
--- a/zephyr/include/emul/tcpc/emul_tcpci_partner_snk.h
+++ b/zephyr/include/emul/tcpc/emul_tcpci_partner_snk.h
@@ -27,12 +27,8 @@
* sink capabilities constructed from given PDOs.
*/
-/** Structure describing sink device emulator */
+/** Structure describing sink device emulator data */
struct tcpci_snk_emul_data {
- /** Common TCPCI partner data */
- struct tcpci_partner_data common_data;
- /** Operations used by TCPCI emulator */
- struct tcpci_emul_partner_ops ops;
/** Power data objects returned in sink capabilities message */
uint32_t pdo[PDO_MAX_OBJECTS];
/** Emulator is waiting for PS RDY message */
@@ -41,28 +37,67 @@ struct tcpci_snk_emul_data {
bool pd_completed;
};
+/** Structure describing standalone sink device emulator */
+struct tcpci_snk_emul {
+ /** Common TCPCI partner data */
+ struct tcpci_partner_data common_data;
+ /** Operations used by TCPCI emulator */
+ struct tcpci_emul_partner_ops ops;
+ /** Sink emulator data */
+ struct tcpci_snk_emul_data data;
+};
+
/**
* @brief Initialise USB-C sink device emulator. Need to be called before
- * any other function.
+ * any other function that is using common_data.
*
- * @param data Pointer to USB-C sink device emulator
+ * @param emul Pointer to USB-C sink device emulator
*/
+void tcpci_snk_emul_init(struct tcpci_snk_emul *emul);
-void tcpci_snk_emul_init(struct tcpci_snk_emul_data *data);
+/**
+ * @brief Initialise USB-C sink device data structure. Single PDO 5V@500mA is
+ * created and all flags are cleared.
+ *
+ * @param data Pointer to USB-C sink device emulator data
+ */
+void tcpci_snk_emul_init_data(struct tcpci_snk_emul_data *data);
/**
* @brief Connect emulated device to TCPCI
*
- * @param data Pointer to USB-C sink device emulator
+ * @param data Pointer to USB-C sink device emulator data
+ * @param common_data Pointer to common TCPCI partner data
+ * @param ops Pointer to TCPCI partner emulator operations
* @param tcpci_emul Pointer to TCPCI emulator to connect
*
* @return 0 on success
* @return negative on TCPCI connect error
*/
int tcpci_snk_emul_connect_to_tcpci(struct tcpci_snk_emul_data *data,
+ struct tcpci_partner_data *common_data,
+ const struct tcpci_emul_partner_ops *ops,
const struct emul *tcpci_emul);
/**
+ * @brief Handle SOP messages as TCPCI sink device. It handles source cap,
+ * get sink cap and ping messages. Accept, Reject and PS_RDY are handled
+ * only if sink emulator send request as response for source cap message
+ * and is waiting for response.
+ *
+ * @param data Pointer to USB-C sink device emulator data
+ * @param common_data Pointer to common TCPCI partner data
+ * @param msg Pointer to received message
+ *
+ * @param TCPCI_PARTNER_COMMON_MSG_HANDLED Message was handled
+ * @param TCPCI_PARTNER_COMMON_MSG_NOT_HANDLED Message wasn't handled
+ */
+enum tcpci_partner_handler_res tcpci_snk_emul_handle_sop_msg(
+ struct tcpci_snk_emul_data *data,
+ struct tcpci_partner_data *common_data,
+ const struct tcpci_emul_msg *msg);
+
+/**
* @}
*/
diff --git a/zephyr/include/emul/tcpc/emul_tcpci_partner_src.h b/zephyr/include/emul/tcpc/emul_tcpci_partner_src.h
index 549afb5cc0..7aa466617b 100644
--- a/zephyr/include/emul/tcpc/emul_tcpci_partner_src.h
+++ b/zephyr/include/emul/tcpc/emul_tcpci_partner_src.h
@@ -27,14 +27,20 @@
* source capabilities constructed from given PDOs.
*/
-/** Structure describing source device emulator */
+/** Structure describing source device emulator data */
struct tcpci_src_emul_data {
+ /** Power data objects returned in source capabilities message */
+ uint32_t pdo[PDO_MAX_OBJECTS];
+};
+
+/** Structure describing standalone source device emulator */
+struct tcpci_src_emul {
/** Common TCPCI partner data */
struct tcpci_partner_data common_data;
/** Operations used by TCPCI emulator */
struct tcpci_emul_partner_ops ops;
- /** Power data objects returned in source capabilities message */
- uint32_t pdo[PDO_MAX_OBJECTS];
+ /** Source emulator data */
+ struct tcpci_src_emul_data data;
};
/** Return values of @ref tcpci_src_emul_check_pdos function */
@@ -53,22 +59,34 @@ enum check_pdos_res {
/**
* @brief Initialise USB-C source device emulator. Need to be called before
- * any other function.
+ * any other function that use @p emul or it's components.
*
- * @param data Pointer to USB-C source device emulator
+ * @param emul Pointer to USB-C source device emulator
+ */
+void tcpci_src_emul_init(struct tcpci_src_emul *emul);
+
+/**
+ * @brief Initialise USB-C source device data structure. Single PDO 5V@3A is
+ * created with fixed unconstrained flag.
+ *
+ * @param data Pointer to USB-C source device emulator data
*/
-void tcpci_src_emul_init(struct tcpci_src_emul_data *data);
+void tcpci_src_emul_init_data(struct tcpci_src_emul_data *data);
/**
* @brief Connect emulated device to TCPCI
*
- * @param data Pointer to USB-C source device emulator
+ * @param data Pointer to USB-C source device emulator data
+ * @param common_data Pointer to USB-C device emulator common data
+ * @param ops Pointer to USB-C device emulato operations
* @param tcpci_emul Poinetr to TCPCI emulator to connect
*
* @return 0 on success
* @return negative on TCPCI connect error or send source capabilities error
*/
int tcpci_src_emul_connect_to_tcpci(struct tcpci_src_emul_data *data,
+ struct tcpci_partner_data *common_data,
+ const struct tcpci_emul_partner_ops *ops,
const struct emul *tcpci_emul);
/**
@@ -100,6 +118,37 @@ int tcpci_src_emul_connect_to_tcpci(struct tcpci_src_emul_data *data,
enum check_pdos_res tcpci_src_emul_check_pdos(struct tcpci_src_emul_data *data);
/**
+ * @brief Send capability message constructed from source device emulator PDOs
+ *
+ * @param data Pointer to USB-C source device emulator data
+ * @param common_data Pointer to common TCPCI partner data
+ * @param delay Optional delay
+ *
+ * @return 0 on success
+ * @return -ENOMEM when there is no free memory for message
+ * @return -EINVAL on TCPCI emulator add RX message error
+ */
+int tcpci_src_emul_send_capability_msg(struct tcpci_src_emul_data *data,
+ struct tcpci_partner_data *common_data,
+ uint64_t delay);
+
+/**
+ * @brief Handle SOP messages as TCPCI source device. It handles request,
+ * get source cap and soft reset messages.
+ *
+ * @param data Pointer to USB-C source device emulator data
+ * @param common_data Pointer to common TCPCI partner data
+ * @param msg Pointer to received message
+ *
+ * @param TCPCI_PARTNER_COMMON_MSG_HANDLED Message was handled
+ * @param TCPCI_PARTNER_COMMON_MSG_NOT_HANDLED Message wasn't handled
+ */
+enum tcpci_partner_handler_res tcpci_src_emul_handle_sop_msg(
+ struct tcpci_src_emul_data *data,
+ struct tcpci_partner_data *common_data,
+ const struct tcpci_emul_msg *msg);
+
+/**
* @}
*/
diff --git a/zephyr/test/drivers/src/integration_usb.c b/zephyr/test/drivers/src/integration_usb.c
index 64a420687c..cbf084a2ab 100644
--- a/zephyr/test/drivers/src/integration_usb.c
+++ b/zephyr/test/drivers/src/integration_usb.c
@@ -65,7 +65,7 @@ static void test_attach_compliant_charger(void)
emul_get_binding(DT_LABEL(TCPCI_EMUL_LABEL));
struct i2c_emul *i2c_emul;
uint16_t battery_status;
- struct tcpci_src_emul_data my_charger;
+ struct tcpci_src_emul my_charger;
const struct device *gpio_dev =
DEVICE_DT_GET(DT_GPIO_CTLR(GPIO_AC_OK_PATH, gpios));
@@ -82,7 +82,9 @@ static void test_attach_compliant_charger(void)
/* Attach emulated charger. */
zassert_ok(gpio_emul_input_set(gpio_dev, GPIO_AC_OK_PIN, 1), NULL);
tcpci_src_emul_init(&my_charger);
- zassert_ok(tcpci_src_emul_connect_to_tcpci(&my_charger, tcpci_emul),
+ zassert_ok(tcpci_src_emul_connect_to_tcpci(&my_charger.data,
+ &my_charger.common_data,
+ &my_charger.ops, tcpci_emul),
NULL);
/* Wait for current ramp. */
@@ -103,7 +105,7 @@ static void test_attach_pd_charger(void)
emul_get_binding(DT_LABEL(TCPCI_EMUL_LABEL));
struct i2c_emul *i2c_emul;
uint16_t battery_status;
- struct tcpci_src_emul_data my_charger;
+ struct tcpci_src_emul my_charger;
const struct device *gpio_dev =
DEVICE_DT_GET(DT_GPIO_CTLR(GPIO_AC_OK_PATH, gpios));
struct ec_params_charge_state charge_params;
@@ -124,7 +126,9 @@ static void test_attach_pd_charger(void)
/* Attach emulated charger. This will send Source Capabilities. */
zassert_ok(gpio_emul_input_set(gpio_dev, GPIO_AC_OK_PIN, 1), NULL);
tcpci_src_emul_init(&my_charger);
- zassert_ok(tcpci_src_emul_connect_to_tcpci(&my_charger, tcpci_emul),
+ zassert_ok(tcpci_src_emul_connect_to_tcpci(&my_charger.data,
+ &my_charger.common_data,
+ &my_charger.ops, tcpci_emul),
NULL);
/* Wait for current ramp. */
@@ -182,7 +186,7 @@ static void test_attach_sink(void)
{
const struct emul *tcpci_emul =
emul_get_binding(DT_LABEL(TCPCI_EMUL_LABEL));
- struct tcpci_snk_emul_data my_sink;
+ struct tcpci_snk_emul my_sink;
/* Set chipset to ON, this will set TCPM to DRP */
test_set_chipset_to_s0();
@@ -192,14 +196,16 @@ static void test_attach_sink(void)
/* Attach emulated sink */
tcpci_snk_emul_init(&my_sink);
- zassert_ok(tcpci_snk_emul_connect_to_tcpci(&my_sink, tcpci_emul),
+ zassert_ok(tcpci_snk_emul_connect_to_tcpci(&my_sink.data,
+ &my_sink.common_data,
+ &my_sink.ops, tcpci_emul),
NULL);
/* Wait for PD negotiation */
k_sleep(K_SECONDS(10));
/* Test if partner believe that PD negotiation is completed */
- zassert_true(my_sink.pd_completed, NULL);
+ zassert_true(my_sink.data.pd_completed, NULL);
/*
* Test that SRC ready is achieved
* TODO: Change it to examining EC_CMD_TYPEC_STATUS