From 21f28eacbc89c80213668956dc8bc8182c3d1b57 Mon Sep 17 00:00:00 2001 From: Sam Hurst Date: Wed, 14 Dec 2022 11:57:26 -0800 Subject: [PATCH] drivers: usb_c: tcpc: stm32: Add GoodCRC timer When operating as a Source, the driver will wait indefinitely for a GoodCRC message from a Sink. This PR adds a timer to trigger a no response when a GoodCRC message isn't received. Signed-off-by: Sam Hurst --- drivers/usb_c/tcpc/ucpd_stm32.c | 17 ++++++++++++----- drivers/usb_c/tcpc/ucpd_stm32_priv.h | 4 ++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/usb_c/tcpc/ucpd_stm32.c b/drivers/usb_c/tcpc/ucpd_stm32.c index f009a5d4819..14fdfe91419 100644 --- a/drivers/usb_c/tcpc/ucpd_stm32.c +++ b/drivers/usb_c/tcpc/ucpd_stm32.c @@ -644,6 +644,8 @@ static void ucpd_manage_tx(struct alert_info *info) */ if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_TX_MSG_SUCCESS)) { ucpd_set_tx_state(info->dev, STATE_WAIT_CRC_ACK); + /* Start the GoodCRC RX Timer */ + k_timer_start(&data->goodcrc_rx_timer, K_USEC(1000), K_NO_WAIT); } else if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_TX_MSG_DISC) || atomic_test_and_clear_bit(&info->evt, UCPD_EVT_TX_MSG_FAIL)) { if (data->tx_retry_count < data->tx_retry_max) { @@ -705,7 +707,10 @@ static void ucpd_manage_tx(struct alert_info *info) /* GoodCRC with matching ID was received */ ucpd_notify_handler(info, TCPC_ALERT_TRANSMIT_MSG_SUCCESS); ucpd_set_tx_state(info->dev, STATE_IDLE); - } else if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_RX_GOOD_CRC)) { + } else if (k_timer_status_get(&data->goodcrc_rx_timer)) { + /* Stop the GoodCRC RX Timer */ + k_timer_stop(&data->goodcrc_rx_timer); + /* GoodCRC w/out match or timeout waiting */ if (data->tx_retry_count < data->tx_retry_max) { ucpd_set_tx_state(info->dev, STATE_ACTIVE_TCPM); @@ -809,9 +814,7 @@ static void ucpd_alert_handler(struct k_work *item) */ do { ucpd_manage_tx(info); - } while (data->ucpd_tx_request && - data->ucpd_tx_state == STATE_IDLE && - !data->ucpd_rx_msg_active); + } while (data->ucpd_tx_state != STATE_IDLE); } /** @@ -1006,7 +1009,8 @@ static void ucpd_isr(const struct device *dev_inst[]) struct tcpc_data *data; uint32_t sr; struct alert_info *info; - uint32_t tx_done_mask = UCPD_SR_TXMSGSENT | + uint32_t tx_done_mask = UCPD_SR_TXUND | + UCPD_SR_TXMSGSENT | UCPD_SR_TXMSGABT | UCPD_SR_TXMSGDISC | UCPD_SR_HRSTSENT | @@ -1226,6 +1230,9 @@ static void ucpd_isr_init(const struct device *dev) struct tcpc_data *data = dev->data; struct alert_info *info = &data->alert_info; + /* Init GoodCRC Receive timer */ + k_timer_init(&data->goodcrc_rx_timer, NULL, NULL); + /* Disable all alert bits */ LL_UCPD_WriteReg(config->ucpd_port, IMR, 0); diff --git a/drivers/usb_c/tcpc/ucpd_stm32_priv.h b/drivers/usb_c/tcpc/ucpd_stm32_priv.h index 7a527ae4c63..ce0a19471a7 100644 --- a/drivers/usb_c/tcpc/ucpd_stm32_priv.h +++ b/drivers/usb_c/tcpc/ucpd_stm32_priv.h @@ -7,6 +7,7 @@ #ifndef ZEPHYR_DRIVERS_USBC_DEVICE_UCPD_STM32_PRIV_H_ #define ZEPHYR_DRIVERS_USBC_DEVICE_UCPD_STM32_PRIV_H_ +#include #include #include #include @@ -308,6 +309,9 @@ struct tcpc_data { struct msg_header_info msg_header; /* Track VCONN on/off state */ bool ucpd_vconn_enable; + + /* Timer for amount of time to wait for receiving a GoodCRC */ + struct k_timer goodcrc_rx_timer; }; #endif /* ZEPHYR_DRIVERS_USBC_DEVICE_UCPD_STM32_PRIV_H_ */