tinyusb icon indicating copy to clipboard operation
tinyusb copied to clipboard

USB CDC not setting tx fifo back to non-overwritable after windows 10 sleep/resume

Open belchercw opened this issue 4 years ago • 3 comments

Set Up

  • PC OS Windows10 Pro version 1909
  • Board imxrt1020_evk (note that issue seems like it would occur regardless of Board type)
  • Firmware examples/device/cdc_msc with the following modification: Replace cdc_task with the following code to allow triggering of writes greater than CFG_TUD_CDC_TX_BUFSIZE
//--------------------------------------------------------------------+
// USB CDC
//--------------------------------------------------------------------+
uint8_t buf[2 * CFG_TUD_CDC_TX_BUFSIZE];
void cdc_task(void)
{
  for (int i = 0; i < CFG_TUD_CDC_TX_BUFSIZE / 2; i++)
  {
    buf[i] = 'a';  //256 'a' characters
    buf[i + CFG_TUD_CDC_TX_BUFSIZE/2] = 'b';  //followed by 256 'b' characters
    buf[i + CFG_TUD_CDC_TX_BUFSIZE] = 'c';  //followed by 256 'c' characters
    buf[i + 3 * CFG_TUD_CDC_TX_BUFSIZE/2] = 'd';  //followed by 256 'd' characters
  }

  {
    // connected and there are data available
    if ( tud_cdc_available() )
    {
      int32_t ch = tud_cdc_read_char();

      if (ch == 'a')
      {
        uint32_t bytes_written = tud_cdc_write(buf, sizeof(buf));
        (void)bytes_written;
        tud_cdc_write_flush();
      }
    }
  }
}

and build with make BOARD=mimxrt1020_evk LOG=1

Describe The Bug When Windows 10 sleeps, TinyUsb sets the state of the cdc tx fifo to "overwritable", but is not resetting it back to non-overwritable after Windows 10 resume from sleep, resulting in discarding of data.

To Reproduce Steps to reproduce:

  • Load the examples/device/cdc_msc example, with specified code changes, onto MIMX1020_EVK board (probably fails on other HW as well).
  • Using Windows 10 as the USB host, and running TeraTerm as the terminal program, open the TinyUsb device's serialport.
  • Pressing 'a' should trigger a transmission of 256 'a' characters followed by 256 'b' characters from the device to the host. This works as expected.
  • Put the Windows 10 computer into sleep mode (Start Menu->Power->Sleep). (Do not close TeraTerm or disconnect USB)
  • Wake with mouse or power button.
  • Press 'a' again in the TeraTerm window. Now 256 'c' characters followed by 256 'd' characters are printed. This is due to the behavior of the tu_fifo_write_n function discarding data when if (!f->overwritable) is false.

Workaround: My original application code was doing the following (pseudocode):

bytes_to_write = larger than CFG_TUD_CDC_TX_BUFSIZE;
while (bytes_to_write)
{
  bytes_written = tud_cdc_write(pbuffer, bytes_to_write);
  pbuffer += bytes_written;
  bytes_to_write -= bytes_written;
  if (bytes_to_write)
  {
    (pend thread until signal from tud_cdc_tx_complete_cb)
  }
}

which worked fine until PC sleep, but fails after resume.

Modifying like so succeeds before and after sleep by avoiding the need to check for fifo overwritable mode:

bytes_to_write = larger than CFG_TUD_CDC_TX_BUFSIZE;
while (bytes_to_write)
{
  //workaround - never pass a size larger than fifo available capacity to tud_cdc_write() 
  real_bytes_to_write = min(bytes_to_write, tud_cdc_write_available())
  bytes_written = tud_cdc_write(pbuffer, real_bytes_to_write);
  pbuffer += bytes_written;
  bytes_to_write -= bytes_written;
  (pend thread until signal from tud_cdc_tx_complete_cb)
}

belchercw avatar Mar 20 '21 17:03 belchercw

Thanks for detail report, please put all code in the triple quote following C '```C' . Also can you run your test with the LOG=2 then post your LOG here as well.

hathach avatar Mar 21 '21 06:03 hathach

Original bug report updated to specify "C" language for code fragment. Rebuilt with LOG=2 and here is the resulting log:

743.txt

belchercw avatar Mar 22 '21 13:03 belchercw

I moved log to its own file since it is too long to post here. I will try to look at the log for analyzing. If you are also troubleshooting it, you could try to comment out the msc descriptors (also update total length), it would be less log to analyze. Or maybe try out the cdc dual ports example,

hathach avatar Mar 23 '21 13:03 hathach