diff options
author | Alec Berg <alecaberg@chromium.org> | 2014-10-10 09:58:20 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-10-15 00:09:55 +0000 |
commit | 2e1c48823cf4cc5e6ba7191d448685bf3d3c4153 (patch) | |
tree | 8c790ce3d48130f7efe0df817297d0598eaa293a | |
parent | 8b0fe914079793de4aa9dfa49ca83619b80e81b8 (diff) | |
download | chrome-ec-2e1c48823cf4cc5e6ba7191d448685bf3d3c4153.tar.gz |
pd: implement sink hard reset counter
For a sink, when there is no source cap packet within SinkWaitCapTimer,
then it sends a hard reset. Once the hard reset has been retried
nHardResetCount times then it shall be assumed that the remote
device is non-responsive, and we stop sending the hard reset.
BUG=none
BRANCH=samus
TEST=Tested with a non-PD charger. When plugged in, we see two hard
resets and then it stops
VBUS 1, 1!
C1 st3
C1 st14
C1 st2
HARD RESET!
[494.906344 HC 0x100]
C1 st3
C1 st14
C1 st2
HARD RESET!
[495.668624 HC 0x100]
C1 st3
> adc
C0_CC1_PD = 20
C1_CC1_PD = 1783
C0_CC2_PD = 36
C1_CC2_PD = 21
V_BOOSTIN = 5329
>
Change-Id: Ib0fc49642aba754015b8055cf1971577b48ac058
Signed-off-by: Alec Berg <alecaberg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/222853
Reviewed-by: Vic Yang <victoryang@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | common/usb_pd_protocol.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 4ed08a64d8..b84a34565a 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -1168,6 +1168,7 @@ void pd_task(void) int res; #ifdef CONFIG_USB_PD_DUAL_ROLE uint64_t next_role_swap = PD_T_DRP_SNK; + int hard_reset_count = 0; #endif enum pd_states this_state; timestamp_t now; @@ -1384,8 +1385,16 @@ void pd_task(void) pd[port].polarity); set_state(port, PD_STATE_SNK_DISCOVERY); timeout = 10*MSEC; + break; } - } else if (drp_state == PD_DRP_TOGGLE_ON && + } + + /* + * If no source detected, reset hard reset counter and + * check for role swap + */ + hard_reset_count = 0; + if (drp_state == PD_DRP_TOGGLE_ON && get_time().val >= next_role_swap) { /* Swap roles to source */ pd[port].role = PD_ROLE_SOURCE; @@ -1399,8 +1408,12 @@ void pd_task(void) break; case PD_STATE_SNK_DISCOVERY: - /* Wait for source cap expired only if we are enabled */ + /* + * Wait for source cap expired only if we are enabled + * and haven't passed the hard reset counter + */ if ((pd[port].last_state != pd[port].task_state) + && hard_reset_count < PD_HARD_RESET_COUNT && pd_comm_enabled) set_state_timeout(port, get_time().val + @@ -1411,6 +1424,7 @@ void pd_task(void) case PD_STATE_SNK_REQUESTED: /* Ensure the power supply actually becomes ready */ set_state(port, PD_STATE_SNK_TRANSITION); + hard_reset_count = 0; timeout = 10 * MSEC; break; case PD_STATE_SNK_TRANSITION: @@ -1448,6 +1462,11 @@ void pd_task(void) PD_STATE_HARD_RESET); break; case PD_STATE_HARD_RESET: +#ifdef CONFIG_USB_PD_DUAL_ROLE + if (pd[port].last_state == PD_STATE_SNK_DISCOVERY) + hard_reset_count++; +#endif + pd_exit_modes(port, payload); send_hard_reset(port); /* reset our own state machine */ |