STM32: Audio driver audio in - Page 1
Forum section: electronics / general

author: MattHollands
author_rank: Frequent Contributor
timestamp: July 04, 2020, 08:08:21 am
content: Hi!I'm trying to configure my STM32F072CB as an audio input device to my computer. My code is based off of the audio driver generated by STM32CubeMX (which is configured as an audio out device) and I've been using SiLabs AN295 to help configure the descriptors but I just can't seem to get it working properly.Before going into details, if anyone has previously written such a driver I'd be very excited to see their code to learn from.I believe I have configured the descriptors correctly as the device shows as a microphone with 2 channels and 30kHz sample rate (as desired). I can even record audio from it (for now I am just generating a saw tooth wave). But there are two issues: 1. I don't really understand my code! 2. I see errors in the WireShark trace that I think should be resolved.1. As I said, the configuration seems correct and I am able to open the sending endpoint. I can see my computer sending isochronous requests to the STM32 of 120 bytes (1ms frame rate, 30kHz, 16 bits, 2 channels) and it is triggering the SOF interrupt, but the DataIn interrupt is never being called - UNLESS I transmit some random data in the SOF interrupt. So my code looks like this:Code:static uint8_t USBD_AUDIO_SOF(USBD_HandleTypeDef *pdev){USBD_AUDIO_HandleTypeDef *haudio;haudio = (USBD_AUDIO_HandleTypeDef *) pdev->pClassData;if(haudio->alt_setting == 1){USBD_LL_Transmit(pdev, 0x03, fakedata, 0);}return USBD_OK;}Code:static uint8_t USBD_AUDIO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum){USBD_AUDIO_HandleTypeDef *haudio;haudio = (USBD_AUDIO_HandleTypeDef *) pdev->pClassData;if(haudio->alt_setting == 1){for(uint8_t i = 0; i < 120; i=i+2){fakedata[i+1] = 120-i;fakedata = 0x00;}USBD_LL_Transmit(pdev, 0x03, fakedata, 120);}/* Only OUT data are processed */return USBD_OK;}Basically I am doing a dummy transmit during SOF interrupt and then sending 120 bytes of data in the DataIn interrupt. This actually seems to work, but when I look in WireShark I see errors. In the image I show the errors in WireShark. You can see the data is counting down from 120 to 0 as expected, but there seems to be a second packet expected that causes an error.So I don't really understand why I need to send a dummy transaction during SOF in order to see the DataIn interrupt. Secondly I don't know what this error means in WireShark.I've pushed the code to my GitHub in case anyone wants to take a closer look:https://github.com/mhollands/STM32-Audio-Input-Device/blob/master/STM32_Audio_Input_Device/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio.cAny help greatly appreciated!

author: Georgy.Moshkin
author_rank: Frequent Contributor
timestamp: October 03, 2025, 04:45:55 am
content: Even though this is an old topic, it seems to be a common issue that leads people here via search. I've spent a week perfecting USB communication for my'mic for youtubers'project and found that USBD_LL_Transmit() has no effect, in the sense that USBD_AUDIO_DataIn() is not triggered on transmit completion as it should be in this code:Code:USBD_LL_OpenEP(pdev, AUDIO_IN_EP, USBD_EP_TYPE_ISOC, USB_BUF_SIZE);pdev->ep_in[AUDIO_IN_EP & 0xFU].is_used = 1U;USBD_LL_FlushEP(pdev, AUDIO_IN_EP);USBD_LL_Transmit(pdev, AUDIO_IN_EP, (uint8_t*)&someData, SEND_SAMPLES * 2);After some investigation I've found out that after endpoint is opened, this code will succeed only after around 5 SOF framesCode:USBD_LL_FlushEP(pdev, AUDIO_IN_EP);USBD_LL_Transmit(pdev, AUDIO_IN_EP, (uint8_t*)&someData, SEND_SAMPLES * 2);AA 11 11 11 11 11 22 22 .....AA - alternate configuration selected and AUDIO_IN_EP is opened.11 - SOF frame transmitting USBD_LL_Transmit() from USBD_AUDIO_SOF() callback22 - USBD_AUDIO_DataIn() is triggered for the first time, no more need to USBD_LL_Transmit() from USBD_AUDIO_SOF().My current workaround is to call USBD_LL_Transmit() from USBD_AUDIO_SOF() untilUSBD_AUDIO_DataIn() is triggered, and then USBD_AUDIO_SOF() is not used anymore.