Yes, host does send a "Set Interface" request.Did host send a "Set Interface" request to select the alternate setting of your output interface?
Yes, USBD_LL_PrepareReceive() is called.You should then make the first call to USBD_LL_PrepareReceive() for receiving data from host.
static uint8_t USBD_AUDIO_SetInterfaceAlternate(USBD_HandleTypeDef *pdev,
uint8_t as_interface_num, uint8_t new_alt)
{
USBD_AUDIO_HandleTypeDef *haudio;
haudio = (USBD_AUDIO_HandleTypeDef*) pdev->pClassData;
if(new_alt == 0)
{
(void)USBD_LL_CloseEP(pdev, AUDIO_OUT_EP);
pdev->ep_out[AUDIO_OUT_EP & 0xFU].is_used = 0U;
pdev->ep_out[AUDIO_OUT_EP & 0xFU].bInterval = 0U;
(void)USBD_LL_CloseEP(pdev, EPNUM_AUDIO_FB);
pdev->ep_in[EPNUM_AUDIO_FB & 0xFU].is_used = 0U;
pdev->ep_in[EPNUM_AUDIO_FB & 0xFU].bInterval = 0U;
}
else
{
pdev->ep_out[AUDIO_OUT_EP & 0xFU].bInterval = AUDIO_HS_BINTERVAL;
(void)USBD_LL_OpenEP(pdev, AUDIO_OUT_EP, USBD_EP_TYPE_ISOC, AUDIO_OUT_PACKET_MAX);
pdev->ep_out[AUDIO_OUT_EP & 0xFU].is_used = 1U;
haudio->wr_ptr = 0U;
haudio->rd_ptr = 0U;
haudio->rd_enable = 0U;
(void)USBD_LL_PrepareReceive(pdev, AUDIO_OUT_EP, haudio->buffer, AUDIO_OUT_PACKET_MAX);
//Feedback
pdev->ep_in[EPNUM_AUDIO_FB & 0xFU].bInterval = 1;
USBD_LL_OpenEP(pdev, EPNUM_AUDIO_FB, USBD_EP_TYPE_ISOC, AUDIO_FEEDBACK_EP_PACKET_SIZE);
USBD_LL_FlushEP(pdev, EPNUM_AUDIO_FB);
pdev->ep_in[EPNUM_AUDIO_FB & 0xFU].is_used = 1U;
get_usb_high_speed_rate(((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->GetPlaybackFeedback());
USBD_LL_Transmit(pdev, EPNUM_AUDIO_FB, AudioFB, AUDIO_FEEDBACK_EP_PACKET_SIZE);
FBAllowed = 0;
}
return USBD_OK;
}
uint8_t as_interface_num, uint8_t new_alt)
{
USBD_AUDIO_HandleTypeDef *haudio;
haudio = (USBD_AUDIO_HandleTypeDef*) pdev->pClassData;
if(new_alt == 0)
{
(void)USBD_LL_CloseEP(pdev, AUDIO_OUT_EP);
pdev->ep_out[AUDIO_OUT_EP & 0xFU].is_used = 0U;
pdev->ep_out[AUDIO_OUT_EP & 0xFU].bInterval = 0U;
(void)USBD_LL_CloseEP(pdev, EPNUM_AUDIO_FB);
pdev->ep_in[EPNUM_AUDIO_FB & 0xFU].is_used = 0U;
pdev->ep_in[EPNUM_AUDIO_FB & 0xFU].bInterval = 0U;
}
else
{
pdev->ep_out[AUDIO_OUT_EP & 0xFU].bInterval = AUDIO_HS_BINTERVAL;
(void)USBD_LL_OpenEP(pdev, AUDIO_OUT_EP, USBD_EP_TYPE_ISOC, AUDIO_OUT_PACKET_MAX);
pdev->ep_out[AUDIO_OUT_EP & 0xFU].is_used = 1U;
haudio->wr_ptr = 0U;
haudio->rd_ptr = 0U;
haudio->rd_enable = 0U;
(void)USBD_LL_PrepareReceive(pdev, AUDIO_OUT_EP, haudio->buffer, AUDIO_OUT_PACKET_MAX);
//Feedback
pdev->ep_in[EPNUM_AUDIO_FB & 0xFU].bInterval = 1;
USBD_LL_OpenEP(pdev, EPNUM_AUDIO_FB, USBD_EP_TYPE_ISOC, AUDIO_FEEDBACK_EP_PACKET_SIZE);
USBD_LL_FlushEP(pdev, EPNUM_AUDIO_FB);
pdev->ep_in[EPNUM_AUDIO_FB & 0xFU].is_used = 1U;
get_usb_high_speed_rate(((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->GetPlaybackFeedback());
USBD_LL_Transmit(pdev, EPNUM_AUDIO_FB, AudioFB, AUDIO_FEEDBACK_EP_PACKET_SIZE);
FBAllowed = 0;
}
return USBD_OK;
}
That way host receive feedback, but device does not recieve audio data. If USBD_LL_Transmit(...) is commented, host does not receive feedback, but device does recieve audio data. Two ways do not work simultaneously.
Not sure it matters but your OUT_EP management is a bit different than mine. I open the OUT_EP when USBD audio is initialized (so only once). When host calls Set Interface for alternate setting 0 I just flush OUT_EP.
Tried that, result is the same. If IN endpoint sends packet first then device only sends packets and do not receive audio data. If OUT endpoint receive packet first then device do not send packets and do receive audio data. What version of USB HAL drivers do you use?I open the OUT_EP when USBD audio is initialized (so only once). When host calls Set Interface for alternate setting 0 I just flush OUT_EP.
Ok, now I understand your explanation. Start sending feedback only after you have received enough data (depends on your buffering scheme). SOF interrupts should occur anyhow if you have SOF enabled in USBD_LL_Init().Tried that, result is the same. If IN endpoint sends packet first then device only sends packets and do not receive audio data. If OUT endpoint receive packet first then device do not send packets and do receive audio data. What version of USB HAL drivers do you use?
I started my development with Nucleo board and external HS PHY but that did not work well with HS. It is practically not possible to connect external HS PHY to Nucleo board since the required pins are scattered all over the board and max trace lengths will be next to impossible to meet. That is why I switched to 723DISCO. And soon after that I made my own board as external I2S clock with 723DISCO is not possible without hacking the board.@bohrok2610 , have you tried your UAC2.0 implementation with external HS PHY?
Tried that. IN packets are enabled when data fills half a buffer, at the very same moment SAI starts outputting buffered data. After IN packets are enabled audio data is not received anymore. Sometimes I can hear sound played cyclically that the buffer has already been filled with. It is like IN packets have priority over OUT packets. So IN packets "push out" OUT packets.Start sending feedback only after you have received enough data (depends on your buffering scheme).
Does "enabled" mean that you start then sending feedback but SOF interrupts are enabled already at initialization?IN packets are enabled when data fills half a buffer...
What STM32F7 board and external HS PHY are you using? IIRC for ULPI the recommended max length of traces (or wires) is about 75mm and length of ULPI signal traces should be within 10mm of CLK trace.
Yes, SOF interrupts are enabled already at initialization in USBD_LL_Init(...) and always active. IN packets are enabled by a variable flag after Interface Alternate swithes from 0 to 1 and the buffer is filled at half of size.Does "enabled" mean that you start then sending feedback but SOF interrupts are enabled already at initialization?
I am using a 4-layer PCB board of my design with ULPI traces length matching to 0,05 mm. MCU is STM32F722VC, HS PHY is USB3300. I tested it in HS applications with interrupt endpoints (HID) and bulk endpoints (custom CDC with DMA enabled). But UAC2.0 is the first application with simultaneous bidirectional (IN and OUT) HS transfers.What STM32F7 board and external HS PHY are you using?
If you receive OUT packets do you still get SOF interrupts?Yes, SOF interrupts are enabled already at initialization in USBD_LL_Init(...) and always active.
Have you tried to run your SW/board with FS?
Yes, SOF interrupts are got when OUT packets are received.If you receive OUT packets do you still get SOF interrupts?
Good idea. I also think in this way.Have you tried to run your SW/board with FS?
So you get SOF interrupts, transmit feedback but host does not appear to get them? If this is the case then it may be due to frame parity. Are you sure you don't get any isochronous IN incomplete interrupts?Yes, SOF interrupts are got when OUT packets are received.
No. I will describe the situation step by step:So you get SOF interrupts, transmit feedback but host does not appear to get them?
1) Plug device into PC, audio stream is not active. Device starts getting SOF interrupts.
2) Start audio stream. Device starts getting Data Out interrupts, receiving audio data and filling it's buffer.
3) As the buffer is filled half of it's size, SAI starts outputting data from the buffer and variable flag is changed to indicate that feedback is allowed to be sent.
4) In the nearest SOF interrupt feedback is transmitted for the first time.
5) After transmitting feedback (step 4) device stops getting Data Out interrupts and audio data is not received any more.
6) From step 5 device only get SOF interrupts and transmit feedback, but it do not receive audio data. Nethertheless I do not get Iso Incomplete interrrupts in device; Windows UAC2.0 log does not contain errors and says audio stream is running and feedback stream is running. It seems like IN packets block OUT packets in device side.
Just tried that, only changed speed to FS and corrected endpoints packets size. Everything works, both data receiving and feedback transmitting. So the same device in UAC2.0 FS mode has no problems described above. The problem relates to HS mode only.Have you tried to run your SW/board with FS?
Ok, sounds like your external PHY has trouble with bidirectional HS transfers. Just one more check: in USBD_LL_Init() do you set hpcd_USB_OTG_HS.Init.phy_itface to USB_OTG_ULPI_PHY?Just tried that, only changed speed to FS and corrected endpoints packets size. Everything works, both data receiving and feedback transmitting. So the same device in UAC2.0 FS mode has no problems described above. The problem relates to HS mode only.
Yes, hpcd.Init.phy_itface = PCD_PHY_ULPI;Just one more check: in USBD_LL_Init() do you set hpcd_USB_OTG_HS.Init.phy_itface to USB_OTG_ULPI_PHY?
PCD_PHY_ULPI = USB_OTG_ULPI_PHY, value is the same, only words are different
@bohrok2610 , thank you very much for help! Need some time to decide what the next step is.
You seem to have similar issue as I had with Nucleo + external PHY board (USB3300): FS worked but not HS. Although in my case it was most probably timing issue due to wire lengths.
HS works with STM32F723DISCO, but as I mentioned it also has shortcomings (external I2S clock). Custom board with STM32F723 is probably the best option but the MCU is out-of-stock until late next year.
HS works with STM32F723DISCO, but as I mentioned it also has shortcomings (external I2S clock). Custom board with STM32F723 is probably the best option but the MCU is out-of-stock until late next year.
Then check out this project at USB3300, STM32F205, XC9536.
https://hirasakastm32ddcdcc.blogspot.com
UAC 2.0 Win 10
16-32bit 384 kHz
DSD DoP x64 i x128
I know this site it is in Japanese, but the code can be understood.
https://hirasakastm32ddcdcc.blogspot.com
UAC 2.0 Win 10
16-32bit 384 kHz
DSD DoP x64 i x128
I know this site it is in Japanese, but the code can be understood.
Well, after many experiments I think the solution is found. Poll interval of data endpoint is encreased to 250 us (bInterval = 2), poll interval of feedback endpoint is encreased to 1 ms (bInterval = 4).
After several hours of streaming device seems to work without transfer errors, it receives audio data and send feedback.
Now I need to correct feedback value in accordance to new poll interval and test for sound correctness and pureness.
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] ENDPOINT_DESCRIPTOR bLength=0x07 bDescriptorType=0x05
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bEndpointAddress 0x01
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bmAttributes 0x05
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] wMaxPacketSize 0x0038
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bInterval 0x02
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] CS_ENDPOINT_DESCRIPTOR bLength=0x08 bDescriptorType=0x25
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bDescriptorSubtype 0x01
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bmAttributes 0x00
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bmControls 0x00
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bLockDelayUnits 0x01
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] wLockDelay 0x01
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] ENDPOINT_DESCRIPTOR bLength=0x07 bDescriptorType=0x05
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bEndpointAddress 0x83
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bmAttributes 0x11
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] wMaxPacketSize 0x0004
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bInterval 0x04
[3]0004.2C70::12/23/2022-01:11:37.155 [USBAudio2] Format Type I PCM (0x00000001) SubSlotSize=2 BitsPerSample=16 ChannelCount=2
[3]0004.2C70::12/23/2022-01:11:37.155 [USBAudio2] Data Endpoint 0x01 Isochronous Asynchronous Data ActualMaxPacketSize=56 ActualPacketFrequency=4000/s (HS Endpoint)
[3]0004.2C70::12/23/2022-01:11:37.155 [USBAudio2] Feedback Endpoint 0x83 Isochronous None Feedback ActualMaxPacketSize=4 ActualPacketFrequency=1000/s (HS Endpoint)
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bEndpointAddress 0x01
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bmAttributes 0x05
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] wMaxPacketSize 0x0038
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bInterval 0x02
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] CS_ENDPOINT_DESCRIPTOR bLength=0x08 bDescriptorType=0x25
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bDescriptorSubtype 0x01
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bmAttributes 0x00
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bmControls 0x00
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bLockDelayUnits 0x01
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] wLockDelay 0x01
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] ENDPOINT_DESCRIPTOR bLength=0x07 bDescriptorType=0x05
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bEndpointAddress 0x83
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bmAttributes 0x11
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] wMaxPacketSize 0x0004
[1]0004.2C70::12/23/2022-01:11:37.154 [USBAudio2] bInterval 0x04
[3]0004.2C70::12/23/2022-01:11:37.155 [USBAudio2] Format Type I PCM (0x00000001) SubSlotSize=2 BitsPerSample=16 ChannelCount=2
[3]0004.2C70::12/23/2022-01:11:37.155 [USBAudio2] Data Endpoint 0x01 Isochronous Asynchronous Data ActualMaxPacketSize=56 ActualPacketFrequency=4000/s (HS Endpoint)
[3]0004.2C70::12/23/2022-01:11:37.155 [USBAudio2] Feedback Endpoint 0x83 Isochronous None Feedback ActualMaxPacketSize=4 ActualPacketFrequency=1000/s (HS Endpoint)
After several hours of streaming device seems to work without transfer errors, it receives audio data and send feedback.
0]0000.0000::12/23/2022-01:11:51.397 [USBAudio2]EP 0x01 OUT stream running at PCM ch=2 sz=16/16 sr=48000
.......................................
[0]0000.0000::12/23/2022-01:11:51.493 [USBAudio2]feedback value 0x0000c000 is out of range [0x000b0000,0x000d0000], ignoring value
[0]0000.0000::12/23/2022-01:11:51.493 [USBAudio2]feedback value 0x0000c000 is out of range [0x000b0000,0x000d0000], ignoring value
[0]0000.0000::12/23/2022-01:11:51.493 [USBAudio2]feedback value 0x0000c000 is out of range [0x000b0000,0x000d0000], ignoring value
[0]0000.0000::12/23/2022-01:11:51.493 [USBAudio2]EP 0x83 FB stream running
.......................................
[0]0000.0000::12/23/2022-01:11:51.493 [USBAudio2]feedback value 0x0000c000 is out of range [0x000b0000,0x000d0000], ignoring value
[0]0000.0000::12/23/2022-01:11:51.493 [USBAudio2]feedback value 0x0000c000 is out of range [0x000b0000,0x000d0000], ignoring value
[0]0000.0000::12/23/2022-01:11:51.493 [USBAudio2]feedback value 0x0000c000 is out of range [0x000b0000,0x000d0000], ignoring value
[0]0000.0000::12/23/2022-01:11:51.493 [USBAudio2]EP 0x83 FB stream running
Now I need to correct feedback value in accordance to new poll interval and test for sound correctness and pureness.
And where is the code there?Then check out this project at USB3300, STM32F205, XC9536.
- Home
- Source & Line
- Digital Line Level
- UAC2.0 on STM32