Skip to content

Conversation

@fcooperti
Copy link

For a single packet read and write operations must pick either 32-bit, 16-bit or 8-bit read or write operations. Mixing and matching can cause corruption of data.

This becomes a bigger issue when using TinyUSB fifo that has to deal with wrapping since read/write operations may be split between multiple transfers of different sizes.

Therefore, create a function that will determine which operation can be used for transfer the entire buffer of data. Then read and write operations can use a parameter to determine what should be used.

fixes #3010

For a single packet read and write operations must pick either 32-bit, 16-bit or
8-bit read or write operations. Mixing and matching can cause corruption of
data.

This becomes a bigger issue when using TinyUSB fifo that has to deal with
wrapping since read/write operations may be split between multiple transfers
of different sizes.

Therefore, create a function that will determine which operation can be used
for transfer the entire buffer of data. Then read and write operations can
use a parameter to determine what should be used.

Signed-off-by: Franklin Cooper Jr <fcooper@ti.com>
@HiFiPhile
Copy link
Collaborator

Thank you for the fix, but the logic can be better.

For example non-fifo based 11 bytes transfer can be 5*16b loops + 1*8b loop.

  • even length -> 32b + 16b transfers
  • odd length -> 16b + 8b transfers

@HiFiPhile
Copy link
Collaborator

@fcooperti, please test my last commit.

After checking kernel source code, the access width change is not limited to the latest operation, for example 32b+16b+8b is allowed for 7 bytes I/O (not limited to 3*16b+8b).

https://github.com/torvalds/linux/blob/19272b37aa4f83ca52bdf9c16d5d81bdd1354494/drivers/usb/musb/musb_core.c#L329

I've updated the logic to make access width limit only applied to wrapped fifo part while keeping normal transfer and linear fifo part untouched.

@HiFiPhile
Copy link
Collaborator

@fcooperti Hello, are you still on this ?

@HiFiPhile
Copy link
Collaborator

@hathach Author is unresponsive, do you have board to test it ?

@fcooperti
Copy link
Author

fcooperti commented Oct 2, 2025 via email

@hathach
Copy link
Owner

hathach commented Oct 3, 2025

I don't have the msp432e but do have tm4c123 which I think pretty the same usbip. I will test again later when having time.

@fcooperti
Copy link
Author

Sorry for the delay. I have been onleave from work and this account is tied to my work email which I haven't been checking while I am out. I'm catching up with the engineer who was working on USB while I was out. Give me a little bit to get back up to speed and I can test this out.

@HiFiPhile
Copy link
Collaborator

Sorry for the delay. I have been onleave from work and this account is tied to my work email which I haven't been checking while I am out. I'm catching up with the engineer who was working on USB while I was out. Give me a little bit to get back up to speed and I can test this out.

@fcooperti Hi, any update ?

@HiFiPhile HiFiPhile mentioned this pull request Dec 10, 2025
Signed-off-by: Zixun LI <admin@hifiphile.com>
Signed-off-by: Zixun LI <admin@hifiphile.com>
Signed-off-by: HiFiPhile <admin@hifiphile.com>
@HiFiPhile
Copy link
Collaborator

HiFiPhile commented Dec 13, 2025

@hathach looking from HIL test the fix is good. musb has another zlp stuck transfer issue #3362 (comment)

@hathach
Copy link
Owner

hathach commented Jan 5, 2026

this should be fixed and superceded by 20d009d as part of #3441

@HiFiPhile
Copy link
Collaborator

this should be fixed and superceded by 20d009d as part of #3441

@hathach That's nice, maybe you can also fix the ZLP ? In handle_xfer_in ZLP will cause the function return early without starting transfer, making the endpoint stuck in busy state. I made a fix:

diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c
index ad20d64bd..cdd4cf8fc 100644
--- a/src/portable/mentor/musb/dcd_musb.c
+++ b/src/portable/mentor/musb/dcd_musb.c
@@ -256,14 +256,14 @@ static void process_setup_packet(uint8_t rhport) {
   }
 }
 
-static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr)
+static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr, bool zlp)
 {
   unsigned epnum = tu_edpt_number(ep_addr);
   unsigned epnum_minus1 = epnum - 1;
   pipe_state_t  *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1];
   const unsigned rem  = pipe->remaining;

-  if (!rem) {
+  if (!rem && !zlp) {
     pipe->buf = NULL;
     return true;
   }
@@ -335,7 +335,7 @@ static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16
   pipe->remaining    = total_bytes;

   if (dir_in) {
-    handle_xfer_in(rhport, ep_addr);
+    handle_xfer_in(rhport, ep_addr, pipe->length == 0);
   } else {
     musb_regs_t* musb_regs = MUSB_REGS(rhport);
     musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum);
@@ -512,7 +512,7 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr)
       ep_csr->tx_csrl &= ~(MUSB_TXCSRL1_STALLED | MUSB_TXCSRL1_UNDRN);
       return;
     }
-    completed = handle_xfer_in(rhport, ep_addr);
+    completed = handle_xfer_in(rhport, ep_addr, false);
   } else {
     // TU_LOG1(" RX CSRL%d = %x\r\n", epn, ep_csr->rx_csrl);
     if (ep_csr->rx_csrl & MUSB_RXCSRL1_STALLED) {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

audio_test - Noisy generated to generated saw tooth tone

3 participants