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