From cd5f7272c8f42777a3e64508a538faa257b9d19a Mon Sep 17 00:00:00 2001 From: QuinnWang Date: Fri, 15 Jan 2021 15:56:18 +0800 Subject: [PATCH] decouple update for DFU "fake" SET_SAMPLE_FREQ special processing DFU will send the AUDIO_STOP_FOR_DFU from endpoint0 to audio core in order to trigger the audio core running dummy_deliver instead of the deliver. The current code didn't distinguish the read SET_SAMPLE_FREQ or "fake" SET_SAMPLE_FREQ (not a real sampFreq, but is AUDIO_STOP_FOR_DFU), so when it is AUDIO_STOP_FOR_DFU, the current decouple code will reset the buffer just as it is sample rate switch, but this will cause the USB hub incorrectly reboot when there is a USB hub connected between XMOS device and the host. The MSFT XUF208 project, using a USB2.0 hub connected to Linux xhci, the error from xhci is "buffer overrun event on the endpoint, followed by a hub re-enabling from khubd. Modified like this commit will solve the problem. So update decouple for DFU "fake" SET_SAMPLE_FREQ special processing just like what did in the ep_buffer. --- lib_xua/src/core/buffer/decouple/decouple.xc | 50 +++++++++++--------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/lib_xua/src/core/buffer/decouple/decouple.xc b/lib_xua/src/core/buffer/decouple/decouple.xc index f217b0e4..84515488 100644 --- a/lib_xua/src/core/buffer/decouple/decouple.xc +++ b/lib_xua/src/core/buffer/decouple/decouple.xc @@ -746,29 +746,32 @@ void XUA_Buffer_Decouple(chanend c_mix_out inuint(c_mix_out); outct(c_mix_out, SET_SAMPLE_FREQ); outuint(c_mix_out, sampFreq); - - inUnderflow = 1; - SET_SHARED_GLOBAL(g_aud_to_host_rdptr, aud_to_host_fifo_start); - SET_SHARED_GLOBAL(g_aud_to_host_wrptr, aud_to_host_fifo_start); - SET_SHARED_GLOBAL(g_aud_to_host_dptr,aud_to_host_fifo_start+4); - - /* Set buffer to send back to zeros buffer */ - SET_SHARED_GLOBAL(g_aud_to_host_buffer, g_aud_to_host_zeros); - - /* Update size of zeros buffer (and sampsToWrite) */ - SetupZerosSendBuffer(aud_to_host_usb_ep, sampFreq, g_curSubSlot_In); - - /* Reset OUT buffer state */ - outUnderflow = 1; - SET_SHARED_GLOBAL(g_aud_from_host_rdptr, aud_from_host_fifo_start); - SET_SHARED_GLOBAL(g_aud_from_host_wrptr, aud_from_host_fifo_start); - SET_SHARED_GLOBAL(aud_data_remaining_to_device, 0); - - if(outOverflow) + + if(sampFreq != AUDIO_STOP_FOR_DFU) { - /* If we were previously in overflow we wont have marked as ready */ - XUD_SetReady_OutPtr(aud_from_host_usb_ep, aud_from_host_fifo_start+4); - outOverflow = 0; + inUnderflow = 1; + SET_SHARED_GLOBAL(g_aud_to_host_rdptr, aud_to_host_fifo_start); + SET_SHARED_GLOBAL(g_aud_to_host_wrptr, aud_to_host_fifo_start); + SET_SHARED_GLOBAL(g_aud_to_host_dptr,aud_to_host_fifo_start+4); + + /* Set buffer to send back to zeros buffer */ + SET_SHARED_GLOBAL(g_aud_to_host_buffer, g_aud_to_host_zeros); + + /* Update size of zeros buffer (and sampsToWrite) */ + SetupZerosSendBuffer(aud_to_host_usb_ep, sampFreq, g_curSubSlot_In); + + /* Reset OUT buffer state */ + outUnderflow = 1; + SET_SHARED_GLOBAL(g_aud_from_host_rdptr, aud_from_host_fifo_start); + SET_SHARED_GLOBAL(g_aud_from_host_wrptr, aud_from_host_fifo_start); + SET_SHARED_GLOBAL(aud_data_remaining_to_device, 0); + + if(outOverflow) + { + /* If we were previously in overflow we wont have marked as ready */ + XUD_SetReady_OutPtr(aud_from_host_usb_ep, aud_from_host_fifo_start+4); + outOverflow = 0; + } } /* Wait for handshake back and pass back up */ @@ -779,7 +782,8 @@ void XUA_Buffer_Decouple(chanend c_mix_out ENABLE_INTERRUPTS(); - speedRem = 0; + if(sampFreq != AUDIO_STOP_FOR_DFU) + speedRem = 0; continue; } #if (AUDIO_CLASS == 2)