summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2014-08-06 17:52:30 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-08-11 09:05:23 +0000
commit5ab558117d1953490140b20dea98fac30bbfff06 (patch)
tree4010b5bd5fae95e4ea2015197a8e749fba2a76f3
parent0d4529c8481a8f4e00ea351a63b0d11d0bb9efe2 (diff)
downloadchrome-ec-5ab558117d1953490140b20dea98fac30bbfff06.tar.gz
pd: use interrupt on Rx retry
After sending a message, we wait for up to 2.7 ms for reply. If we don't get one, we retry for up to twice. Therefore, a undelivered message could take up to >8ms. To prevent starving other tasks, let's yield to other tasks on retries and rely on interrupt to wake us. BUG=chrome-os-partner:28341 TEST=Plug in zinger on port 0 and C-to-A dongle on port 1. Check that port 0 drops connection less frequently. BRANCH=None Change-Id: If85a70fd1140fef69d79243b198703ce601f8030 Signed-off-by: Vic Yang <victoryang@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/211281 Reviewed-by: Alec Berg <alecaberg@chromium.org>
-rw-r--r--chip/stm32/usb_pd_phy.c4
-rw-r--r--common/usb_pd_protocol.c16
-rw-r--r--include/usb_pd.h3
3 files changed, 19 insertions, 4 deletions
diff --git a/chip/stm32/usb_pd_phy.c b/chip/stm32/usb_pd_phy.c
index bbe923b024..a19bcc7969 100644
--- a/chip/stm32/usb_pd_phy.c
+++ b/chip/stm32/usb_pd_phy.c
@@ -531,8 +531,8 @@ void pd_hw_init(int port)
/* Auto-reload value : 16-bit free running counter */
phy->tim_rx->arr = 0xFFFF;
- /* Timeout for message receive : 2.7ms */
- phy->tim_rx->ccr[2] = 2400000 * 27 / 10000;
+ /* Timeout for message receive */
+ phy->tim_rx->ccr[2] = (2400000 / 1000) * USB_PD_RX_TMOUT_US / 1000;
/* Timer ICx input configuration */
if (TIM_CCR_IDX(port) == 1)
phy->tim_rx->ccmr1 |= TIM_CCR_CS << 0;
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 80aeb7b860..371e03ead5 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -334,8 +334,20 @@ static int send_validate_message(int port, uint16_t header,
/* Transmit the packet */
pd_start_tx(port, pd[port].polarity, bit_len);
pd_tx_done(port, pd[port].polarity);
- /* starting waiting for GoodCrc */
- pd_rx_start(port);
+ /*
+ * If we failed the first try, enable interrupt and yield
+ * to other tasks, so that we don't starve them.
+ */
+ if (r) {
+ pd_rx_enable_monitoring(port);
+ /* Message receive timeout is 2.7ms */
+ if (task_wait_event(USB_PD_RX_TMOUT_US) ==
+ TASK_EVENT_TIMER)
+ continue;
+ } else {
+ /* starting waiting for GoodCrc */
+ pd_rx_start(port);
+ }
/* read the incoming packet if any */
head = analyze_rx(port, payload);
pd_rx_complete(port);
diff --git a/include/usb_pd.h b/include/usb_pd.h
index e472e5bcf5..38f58f5888 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -133,6 +133,9 @@ enum pd_errors {
/* USB Vendor ID assigned to Google Inc. */
#define USB_VID_GOOGLE 0x18d1
+/* Timeout for message receive in microseconds */
+#define USB_PD_RX_TMOUT_US 2700
+
/* --- Protocol layer functions --- */
#ifdef CONFIG_USB_PD_DUAL_ROLE