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í
parent c659f3d8d7
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)) {
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);

View file

@ -7,6 +7,7 @@
#ifndef 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/drivers/usb_c/usbc_tcpc.h>
#include <zephyr/drivers/pinctrl.h>
@ -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_ */