cancel
Showing results for 
Search instead for 
Did you mean: 

Having problem setting up USB Audio(Microphone) for STM32H743

NBin .1
Associate II

Hello,

I am having problem configuring usb audio microphone for STM32H743-Nucleo144.

What I want to do is to connect several microphones (actually more than 8 microphone but that will be another issue, so I will just stick to 8 microphones) to STM32H743 through DFSDM and forward the PCM data to (audio) USB. I think I already figure out configuring the DFSDM but now having problem with USB audio. The setting that I would like to have is 24 bit and 48kHz.

The generated code for the USB audio was configured for speaker, so I need to change the usbd_audio.h/c file somehow. I found an example code but from STM32L476 + CCA02M2. So I replace the usbd_audio(was configured for speaker) with usbd_audio_in(configured for microphone) from the CCA02M2 example. That does not seems to work for H743(I did try generating my own code with STM32L476 , replace usbd_audio with usbd_audio_in and modified and add some code. It works).

Later on I found an example program called X-CUBE-USB-AUDIO and going through the STM32F769I_DISCO_UAC10-REC. This code looks promising but I am still having trouble to understand and implement the code. The code looks kind of similar to CCA02M2 but the flow is different.

For example,in CCA02M2 the usb configuration written in main() are as follows(Notice that usb descriptor was called before USBD_Init() :(

//The USB descriptor is called at the start
  USBD_AUDIO_Init_Microphone_Descriptor(&hUSBDDevice, AUDIO_IN_SAMPLING_FREQUENCY, AUDIO_IN_CHANNELS);
 
  USBD_Init(&hUSBDDevice, &AUDIO_Desc, 0);
 
  USBD_RegisterClass(&hUSBDDevice, &USBD_AUDIO);
 
  USBD_AUDIO_RegisterInterface(&hUSBDDevice, &USBD_AUDIO_fops);
 
  USBD_Start(&hUSBDDevice);

But in X-CUBE-USB-AUDIO(STM32F769I_DISCO_UAC10-REC) , the same usb configurations were used but the implementation is different. The usb descriptor was called if I am not mistaken in USBD_AUDIO_RegisterInterface().  

//In main()
  USBD_Init(&USBD_Device, &AUDIO_Desc, 0);
 
  USBD_RegisterClass(&USBD_Device, USBD_AUDIO_CLASS);
  
  USBD_AUDIO_RegisterInterface(&USBD_Device, &audio_class_interface);
  
  USBD_Start(&USBD_Device);
//--------------------------------------------------------------------------------------------------------
//The USB Description was called inside USBD_AUDIO_RegisterInterface(..)
 
uint8_t  USBD_AUDIO_RegisterInterface  (USBD_HandleTypeDef   *pdev, 
                                        USBD_AUDIO_InterfaceCallbacksfTypeDef *aifc)
{
  if(aifc != NULL)
  {
    pdev->pUserData= aifc;
    aifc->GetConfigDesc(&USBD_AUDIO_CfgDesc, &USBD_AUDIO_CfgDescSize, aifc->private_data);
    
  }
  return 0;
}

Both program kind of want to do the same thing, which is configuring and initialize the audio usb but they are implemented differently under the hood. Example A call the USB descriptor at this point and Example B call the USB descriptor at different point.

Another problem is, the code example in CCA02M2 create completely new functions and new struct instead of using the one generated by cube ide, so now I am really confuse if I should add this function or the code example just redefine the code that already generated.

So now, when I generate my code and want to implement the 2 example in my code, it is really difficult and confusing. What do I need to change to implement usb audio microphone so that it has the setting of 24 bit and 48kHz. Is it just usbd_audio.h/c? or other file like usbd_core,usbd_ctlreq, usbd_def, usbd_ioreq, usbd_audio_if, usb_device?

I change the bSubFrameSize and bBitResolution in the usbd_audio_in.c that I got from CCA02M2, so that setting is 24 bit and 48kHz but my USB was not recognised.

Can anyone help me?

Thanks in advance.

4 REPLIES 4
Gabriel Melo
Associate III

Heyy! I have the exact same problem so maybe we could help each other out.

I began by taking the code in an expansion package since STM32CubeIDE only generates code for a USB speaker.

There are two expansion packages that could help you: X-CUBE-USB-AUDIO and X-CUBE-MEMSMIC1. The first one is very complete, however it introduces too many functions and is very hard to integrate into your code (at least in my case). So I went with the second one (X-CUBE-MEMSMIC1).

I follow those steps in another question I posted a while ago: STM32 USB Audio Device (microphone) with 24-bit resolution (see comments)

And I also replaced the usbd_audio_if .c and .h files in my folder with those of the expansion package.

For now I can get my USB device mounted but I just cannot send the samples (I do not know where to put them in the code).

Regards and stay in contact,

NBin .1
Associate II

Heyy!

Sorry for my late reply, I was in holiday. Thank you for your reply.

Actually I saw your post and that is how I know which files to replace and came to conclusion that the generated code is for speaker. Your post was around 1.5 year ago, so I thought you already solved this issue and might forget about it if I ask. Did you manage to configure your setting to 24 bit? Because my configuration for 24 bit was not succesful. When I changed the line that you comment e.g from 2 to 3, the USB was not detected. When I change it back to original, then it is alright.

I also saw the replies and follow what @Community member​ suggested but it also didnt work.

To send the samples, I think I have a rough idea but idk if it works because my usb is not working. So I saw this code in github y2kblog/NUCLEO-L476RG_DFSDM_PDM-Mic. He sends the sample to UART not USB but I still can see something coming out of the terminal although it is all gibberish. So this basically means that the communication take place. Fundamentally it look like the following: (This is just a rough idea and not the proper way to do it. What I want to emphasize is that you can get the samples through the callback function "HAL_DFSDM_FilterRegConvCpltCallback" although it will be truncated to smaller size and a lot of information will be loss)

//buffer is a global variable, I forget what its size
int32_t buffer[length]={0};
int main(){
   ...
   //Initialization
   if (HAL_DFSDM_FilterRegularStart_DMA(&hdfsdm1_filter0, buffer, length) != HAL_OK)
   {
        Error_Handler();
   }
   ...
   while(1){..}
}
 
void HAL_DFSDM_FilterRegConvHalfCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
{
   ... 
}
 
void HAL_DFSDM_FilterRegConvCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
{
  //Obtain buffer and send it to uart
  HAL_UART_Transmit(&huart2, (uint8_t*)buffer, (uint16_t)length, 0xFFFFFFFF)
}

But I think with usb it will be much more complicated, I dont think there is a single callback function to transmit data like uart has. Btw, are you using L476 or H743? And how many microphones you want to connect to your microcontroller?

Regards

Nafiz

Okay, so, once you change the USB descriptors make sure you uninstall your device on windows, and then plug it in again... Windows does not recognize a USB device with the same VID and PID if it has changed the descriptors (the same is not true on Linux, for example).

I had more luck using the X-CUBE-USB-AUDIO package, altough it is not cube-compatible. My mic works much better (it is not 100% tough). What you need to do is:

  • Generate code with stm32cubeide for usb audio device
  • Replace files with those on the expansion package but keep those on the Core (Middlewares/ST/STM32_Device_Library/Core) and Target (USB_MIC/Target) folders. The usbd_conf files are device-specific (more on that here: STM32 USB training - 08 STM32 USB Device library - YouTube at around the 4 min mark)
  • Make sure you use the STM32F769I_DISCO_UAC10-DUM example, for a dummy microphone (easier to decouple from the software used for the MEMS mic)

And then, you configure as your application should run :

  • Have your audio samples transferred by DMA
  • Once you get the HalfTransferComplete and TransferComplete callbacks, call the AUDIO_Fill_Buffer function (you can take a hint by looking at the implementation on STM32F769I_DISCO_UAC10-REC (Application/User/audio_mic_node.c). Try to implement the important functions on audio_mic_node.c to your audio_dummymic_node.c that is in your project. I think you only have to modify this file and the usbd_user_cfg.h file

Tell me if you have any questions, and good luck ! If you can make it work 100% (or at least 90) please post your updates.

Regards

Hello @Gabriel Melo​ ,

This is my another account and I am the one posting the question above. I have a question and maybe you can help me. I have a problem setting up the output clock for the DFSDM and I want to have 48 kHz x 64 = 3.072 MHz freq on the DFSDM1_CKOUT to feed it into the microphones. But the problem is it didnt work. My DFSDM Clock source is 49.142857 MHz and the divider is 16 so I will expect to get 3.072 MHz on the DFSDM1_CKOUT but what I got is 978 kHz. I post my question here and I hope you can help me.