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 <sbh1187@gmail.com>
This commit is contained in:
Sam Hurst 2022-12-14 11:57:26 -08:00 committed by Carles Cufí
commit 21f28eacbc
2 changed files with 16 additions and 5 deletions

View file

@ -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)) { if (atomic_test_and_clear_bit(&info->evt, UCPD_EVT_TX_MSG_SUCCESS)) {
ucpd_set_tx_state(info->dev, STATE_WAIT_CRC_ACK); 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) || } 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)) { atomic_test_and_clear_bit(&info->evt, UCPD_EVT_TX_MSG_FAIL)) {
if (data->tx_retry_count < data->tx_retry_max) { 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 */ /* GoodCRC with matching ID was received */
ucpd_notify_handler(info, TCPC_ALERT_TRANSMIT_MSG_SUCCESS); ucpd_notify_handler(info, TCPC_ALERT_TRANSMIT_MSG_SUCCESS);
ucpd_set_tx_state(info->dev, STATE_IDLE); 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 */ /* GoodCRC w/out match or timeout waiting */
if (data->tx_retry_count < data->tx_retry_max) { if (data->tx_retry_count < data->tx_retry_max) {
ucpd_set_tx_state(info->dev, STATE_ACTIVE_TCPM); ucpd_set_tx_state(info->dev, STATE_ACTIVE_TCPM);
@ -809,9 +814,7 @@ static void ucpd_alert_handler(struct k_work *item)
*/ */
do { do {
ucpd_manage_tx(info); ucpd_manage_tx(info);
} while (data->ucpd_tx_request && } while (data->ucpd_tx_state != STATE_IDLE);
data->ucpd_tx_state == STATE_IDLE &&
!data->ucpd_rx_msg_active);
} }
/** /**
@ -1006,7 +1009,8 @@ static void ucpd_isr(const struct device *dev_inst[])
struct tcpc_data *data; struct tcpc_data *data;
uint32_t sr; uint32_t sr;
struct alert_info *info; 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_TXMSGABT |
UCPD_SR_TXMSGDISC | UCPD_SR_TXMSGDISC |
UCPD_SR_HRSTSENT | UCPD_SR_HRSTSENT |
@ -1226,6 +1230,9 @@ static void ucpd_isr_init(const struct device *dev)
struct tcpc_data *data = dev->data; struct tcpc_data *data = dev->data;
struct alert_info *info = &data->alert_info; struct alert_info *info = &data->alert_info;
/* Init GoodCRC Receive timer */
k_timer_init(&data->goodcrc_rx_timer, NULL, NULL);
/* Disable all alert bits */ /* Disable all alert bits */
LL_UCPD_WriteReg(config->ucpd_port, IMR, 0); LL_UCPD_WriteReg(config->ucpd_port, IMR, 0);

View file

@ -7,6 +7,7 @@
#ifndef ZEPHYR_DRIVERS_USBC_DEVICE_UCPD_STM32_PRIV_H_ #ifndef ZEPHYR_DRIVERS_USBC_DEVICE_UCPD_STM32_PRIV_H_
#define ZEPHYR_DRIVERS_USBC_DEVICE_UCPD_STM32_PRIV_H_ #define ZEPHYR_DRIVERS_USBC_DEVICE_UCPD_STM32_PRIV_H_
#include <zephyr/kernel.h>
#include <zephyr/sys/util.h> #include <zephyr/sys/util.h>
#include <zephyr/drivers/usb_c/usbc_tcpc.h> #include <zephyr/drivers/usb_c/usbc_tcpc.h>
#include <zephyr/drivers/pinctrl.h> #include <zephyr/drivers/pinctrl.h>
@ -308,6 +309,9 @@ struct tcpc_data {
struct msg_header_info msg_header; struct msg_header_info msg_header;
/* Track VCONN on/off state */ /* Track VCONN on/off state */
bool ucpd_vconn_enable; 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_ */ #endif /* ZEPHYR_DRIVERS_USBC_DEVICE_UCPD_STM32_PRIV_H_ */