dcd/ch32fs: set EP to NAK earlier to reduce spuroius transfer

Signed-off-by: HiFiPhile <admin@hifiphile.com>
This commit is contained in:
HiFiPhile
2026-05-23 13:02:53 +02:00
parent b3141bb259
commit e14b0e8514

View File

@ -66,6 +66,13 @@ static struct {
static void update_in(uint8_t rhport, uint8_t ep, bool force) {
struct usb_xfer* xfer = &data.xfer[ep][TUSB_DIR_IN];
if (xfer->valid) {
// Set EP to NAK to avoid spurious tramsfer
if (ep == 0) {
EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK | (data.ep0_tog ? USBFS_EP_T_TOG : 0);
} else if (!data.isochronous[ep]) {
EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NAK;
}
if (force || xfer->len) {
size_t len = TU_MIN(xfer->max_size, xfer->len);
if (ep == 0) {
@ -101,6 +108,13 @@ static void update_in(uint8_t rhport, uint8_t ep, bool force) {
static void update_out(uint8_t rhport, uint8_t ep, size_t rx_len) {
struct usb_xfer* xfer = &data.xfer[ep][TUSB_DIR_OUT];
if (xfer->valid) {
// Set EP to NAK to avoid spurious tramsfer
if (ep == 0) {
EP_RX_CTRL(0) = USBFS_EP_R_RES_NAK;
} else if (!data.isochronous[ep]) {
EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~USBFS_EP_R_RES_MASK) | USBFS_EP_R_RES_NAK;
}
size_t len = TU_MIN(xfer->max_size, TU_MIN(xfer->len, rx_len));
if (ep == 3) {
memcpy(xfer->buffer, data.ep3_buffer.out, len);
@ -116,9 +130,7 @@ static void update_out(uint8_t rhport, uint8_t ep, size_t rx_len) {
dcd_event_xfer_complete(rhport, ep, xfer->processed_len, XFER_RESULT_SUCCESS, true);
}
if (ep == 0) {
EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK;
} else {
if (ep != 0) {
uint8_t rx_res = data.isochronous[ep]
? USBFS_EP_R_RES_NYET
: (xfer->valid ? USBFS_EP_R_RES_ACK : USBFS_EP_R_RES_NAK);
@ -173,10 +185,11 @@ void dcd_int_handler(uint8_t rhport) {
if (status & USBFS_INT_FG_TRANSFER) {
uint8_t ep = USBFS_INT_ST_MASK_UIS_ENDP(USBOTG_FS->INT_ST);
uint8_t token = USBFS_INT_ST_MASK_UIS_TOKEN(USBOTG_FS->INT_ST);
uint16_t rx_len = USBOTG_FS->RX_LEN;
USBOTG_FS->INT_FG = USBFS_INT_FG_TRANSFER;
switch (token) {
case PID_OUT: {
uint16_t rx_len = USBOTG_FS->RX_LEN;
update_out(rhport, ep, rx_len);
break;
}
@ -198,7 +211,6 @@ void dcd_int_handler(uint8_t rhport) {
break;
}
USBOTG_FS->INT_FG = USBFS_INT_FG_TRANSFER;
} else if (status & USBFS_INT_FG_BUS_RST) {
data.ep0_tog = true;
data.xfer[0][TUSB_DIR_OUT].max_size = 64;