Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 37 additions & 2 deletions drivers/usb/udc/udc_stm32.c
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commit message does not look nice. You can have up to 75 characters per line in the commit message.

Manage endpoint halt state explicitly in set/clear halt functions.
Prevent transmissions on halted endpoints in enqueue function.
Trigger retransmission post-halt clearance if applicable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,14 @@ static int udc_stm32_ep_set_halt(const struct device *dev,
return -EIO;
}

/*
* Mark non-control endpoint as halted
* to indicate stall condition
*/
if (USB_EP_GET_IDX(cfg->addr) != 0) {
cfg->stat.halted = true;
}

return 0;
}

Expand All @@ -847,6 +855,22 @@ static int udc_stm32_ep_clear_halt(const struct device *dev,
return -EIO;
}

/* Clear halted state to resume normal operation */
cfg->stat.halted = false;

if (USB_EP_GET_IDX(cfg->addr) != 0U) {
struct net_buf *buf = udc_buf_peek(cfg);

/* Start IN (device-to-host) transfer if not busy */
if (buf != NULL && USB_EP_DIR_IS_IN(cfg->addr) && !udc_ep_is_busy(cfg)) {
udc_stm32_tx(dev, cfg, buf);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the OUT direction? Do you need to restart anything explicitly here? I did not have time to look at the OUT path in my suggestion, so I just added a comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point regarding the OUT direction. For OUT endpoints, I will add logic to re-arm the endpoint (e.g., by calling udc_stm32_rx()) to ensure it is ready to receive new data.
I’ll update the code accordingly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

/* Prepare OUT (host-to-device) transfer if busy */
else if (buf != NULL && USB_EP_DIR_IS_OUT(cfg->addr) && udc_ep_is_busy(cfg)) {
udc_stm32_rx(dev, cfg, buf);
}
}

return 0;
}

Expand Down Expand Up @@ -879,8 +903,19 @@ static int udc_stm32_ep_enqueue(const struct device *dev,

lock_key = irq_lock();

if (USB_EP_DIR_IS_IN(epcfg->addr)) {
ret = udc_stm32_tx(dev, epcfg, buf);
if (USB_EP_DIR_IS_IN(epcfg->addr) != 0U) {
if (!epcfg->stat.halted) {
/* Endpoint is not halted, safe to transmit data */
ret = udc_stm32_tx(dev, epcfg, buf);
} else {
/*
* Endpoint is halted (stalled) by the host.
* Skip transmission to avoid protocol violations
* and potential data corruption.
*/
LOG_DBG("ep 0x%02x halted", epcfg->addr);
ret = 0;
}
} else {
ret = udc_stm32_rx(dev, epcfg, buf);
}
Expand Down