tinyusb icon indicating copy to clipboard operation
tinyusb copied to clipboard

Endpoints are not being closed on RP2040

Open vmilea opened this issue 4 years ago • 2 comments

Operating System

Others

Board

Raspberry Pi Pico

Firmware

What happened ?

The dcd_edpt_close() implementation in dcd_rp2040.c is incomplete. It was probably meant to call hw_endpoint_close, but that code remains commented out.

With USB audio playback it's common for the endpoints to close and reopen as needed. During silence, the driver selects alternate setting 0 to conserve bandwidth and the endpoint is closed. Then it's reopened when playback starts.

Because the endpoints are not properly closed on RP2040, there are warnings like:

WARN: starting new transfer on already active ep 1 out

and eventually it runs out of buffer space with failed assert hw_data_offset(next_buffer_ptr) <= USB_DPRAM_MAX.

How to reproduce ?

Close and reopen endpoints repeatedly.

Debug Log

Screenshots

vmilea avatar Dec 04 '21 14:12 vmilea

Pull request submitted. A couple of notes:

  • To keep is simple, buffer space is only reclaimed after all non-control endpoints have closed.
  • If a transfer event gets delivered late, after closing the endpoint, it will be ignored. This never happened in my testing.

vmilea avatar Dec 04 '21 14:12 vmilea

Why this (more complicated) partial fix that actually seems to introduce a new issue (see below) instead of simply not assigning endpoint buffers multiple times?

Assuming reset_non_control_endpoints() will be called at a safe time: in _hw_endpoint_alloc() an if (!ep->hw_data_buf) around the assignment from next_buffer_ptr would fix it for all cases, right? That is, the warning will remain but no panics anymore and everything keeps functioning as expected. Note that hw_endpoint_close() must be #if 0'ed again, but do keep the hard_assert.

  if (!ep->hw_data_buf) {
    ep->hw_data_buf = next_buffer_ptr;
    next_buffer_ptr += size;
  }

With the current fix and just an audio device I think I have the 'transfer event delivered late' bit reproducible, resulting in a "Can't continue xfer on inactive ep 0 out" panic. On a Raspberry Pi 3 I have a test application that transfers audio for 2 seconds then shuts down and is restarted after 1 second. The RP2040 is an audio device that simply echos audio received. The panic occurs mostly within one minute.

geurtv avatar May 13 '22 14:05 geurtv