diff --git a/type-c-service/src/wrapper/pd.rs b/type-c-service/src/wrapper/pd.rs index f55bd8bb..5564c3b2 100644 --- a/type-c-service/src/wrapper/pd.rs +++ b/type-c-service/src/wrapper/pd.rs @@ -55,15 +55,23 @@ where return Err(PdError::InvalidPort); } - let deadline = &mut state + let port_state = state .port_states_mut() .get_mut(port.0 as usize) - .ok_or(PdError::InvalidPort)? - .sink_ready_deadline; + .ok_or(PdError::InvalidPort)?; - if new_contract && !sink_ready { + let contract_changed = port_state.status.available_sink_contract != status.available_sink_contract; + let deadline = &mut port_state.sink_ready_deadline; + + // Don't start the timeout if the sink has signaled it's ready or if the contract didn't change. + // The latter ensures that soft resets won't continually reset the ready timeout + debug!( + "Port{}: Check sink ready: new_contract={:?}, sink_ready={:?}, contract_changed={:?}, deadline={:?}", + port.0, new_contract, sink_ready, contract_changed, deadline, + ); + if new_contract && !sink_ready && contract_changed { // Start the timeout - // Double the spec maximum transition time to provide a safety margin for hardware/controller delays our out-of-spec controllers. + // Double the spec maximum transition time to provide a safety margin for hardware/controller delays or out-of-spec controllers. let timeout_ms = if status.epr { T_PS_TRANSITION_EPR_MS } else { @@ -77,7 +85,6 @@ where } else if deadline.is_some() && (!status.is_connected() || status.available_sink_contract.is_none() || sink_ready) { - // Clear the timeout debug!("Port{}: Sink ready timeout cleared", port.0); *deadline = None; }