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.
This commit is contained in:
QuinnWang
2021-01-15 15:56:18 +08:00
committed by GitHub
parent c9299fce96
commit cd5f7272c8

View File

@@ -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)