diff --git a/include/zephyr/usb_c/usbc.h b/include/zephyr/usb_c/usbc.h index 59aae4d992..21053fc16c 100644 --- a/include/zephyr/usb_c/usbc.h +++ b/include/zephyr/usb_c/usbc.h @@ -109,6 +109,10 @@ enum usbc_policy_notify_t { POWER_CHANGE_1A5, /** Sink SubPower state a 5V / 3A */ POWER_CHANGE_3A0, + /** Sender Response Timeout */ + SENDER_RESPONSE_TIMEOUT, + /** Source Capabilities Received */ + SOURCE_CAPABILITIES_RECEIVED, }; /** diff --git a/subsys/usb/usb_c/usbc_pe_common.c b/subsys/usb/usb_c/usbc_pe_common.c index b7d1edf485..024e40e362 100644 --- a/subsys/usb/usb_c/usbc_pe_common.c +++ b/subsys/usb/usb_c/usbc_pe_common.c @@ -702,10 +702,9 @@ void pe_drs_send_swap_run(void *obj) return; } + /* Transition to PE_SNK_READY on SenderResponseTimer timeout */ if (usbc_timer_expired(&pe->pd_t_sender_response)) { - /* Protocol Error */ - policy_notify(dev, PROTOCOL_ERROR); - pe_send_soft_reset(dev, PD_PACKET_SOP); + pe_set_state(dev, PE_SNK_READY); } } diff --git a/subsys/usb/usb_c/usbc_pe_snk_states.c b/subsys/usb/usb_c/usbc_pe_snk_states.c index 49362cd057..5759703e48 100644 --- a/subsys/usb/usb_c/usbc_pe_snk_states.c +++ b/subsys/usb/usb_c/usbc_pe_snk_states.c @@ -177,6 +177,9 @@ void pe_snk_evaluate_capability_entry(void *obj) LOG_INF("PE_SNK_Evaluate_Capability"); + /* Inform the DPM of the reception of the source capabilities */ + policy_notify(dev, SOURCE_CAPABILITIES_RECEIVED); + header = prl_rx->emsg.header; /* Reset Hard Reset counter to zero */ @@ -606,7 +609,12 @@ void pe_snk_get_source_cap_entry(void *obj) LOG_INF("PE_SNK_Get_Source_Cap"); - /* Send a Get_Source_Cap Message */ + /* + * On entry to the PE_SNK_Get_Source_Cap state the Policy Engine + * Shall request the Protocol Layer to send a get Source + * Capabilities message in order to retrieve the Source’s + * capabilities. + */ pe_send_ctrl_msg(dev, PD_PACKET_SOP, PD_CTRL_GET_SOURCE_CAP); } @@ -619,12 +627,34 @@ void pe_snk_get_source_cap_run(void *obj) const struct device *dev = pe->dev; struct usbc_port_data *data = dev->data; struct protocol_layer_rx_t *prl_rx = data->prl_rx; + union pd_header header; /* Wait until message is sent or dropped */ if (atomic_test_and_clear_bit(pe->flags, PE_FLAGS_TX_COMPLETE)) { + /* The Policy Engine Shall then start the SenderResponseTimer. */ + usbc_timer_start(&pe->pd_t_sender_response); + } + /* + * The Policy Engine Shall transition to the PE_SNK_Evaluate_Capability + * State when: + * 1: In SPR Mode and SPR Source Capabilities were requested and + * a Source_Capabilities Message is received + */ + else if (atomic_test_and_clear_bit(pe->flags, PE_FLAGS_MSG_RECEIVED)) { + header = prl_rx->emsg.header; + + if (received_control_message(dev, header, PD_DATA_SOURCE_CAP)) { + pe_set_state(dev, PE_SNK_EVALUATE_CAPABILITY); + } + } + /* + * The Policy Engine Shall transition to the PE_SNK_Ready state when: + * 1: The SenderResponseTimer times out. + */ + else if (usbc_timer_expired(&pe->pd_t_sender_response)) { pe_set_state(dev, PE_SNK_READY); - } else if (atomic_test_and_clear_bit(pe->flags, PE_FLAGS_MSG_DISCARDED)) { - pe_send_soft_reset(dev, prl_rx->emsg.type); + /* Inform the DPM of the sender response timeout */ + policy_notify(dev, SENDER_RESPONSE_TIMEOUT); } }