cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F072 usb audio

sgpiqx
Associate II
Posted on May 19, 2016 at 04:45

Hi guys,

I new to STM32, was mostly use PIC32 for USB audio application but due to cost decided to switch to STM Now I have STM32F0 discovery board with STM32F072RBT6. I tried to setup USB audio with CubeMX and compile with out no issue. Now I would like to change the Audio Sampling rate to 48KHz instead of 1KHz (code default value). Once change to 48KHz, the code will run into Hard Fault exception. So I take a look into the code and sort of does not understand below part (summarize from various .h and .c)

#define USBD_malloc (uint32_t *)USBD_static_malloc
#define USBD_AUDIO_FREQ 22100
#define AUDIO_OUT_PACKET (uint32_t)(((USBD_AUDIO_FREQ * 2 * 2) /1000)) //=4=88bytes
/* Number of sub-packets in the audio transfer buffer. You can modify this value but always make sure
that it is an even number and higher than 3 */
#define AUDIO_OUT_PACKET_NUM 80
/* Total size of the audio transfer buffer = 88*80=7040 bytes!*/
#define AUDIO_TOTAL_BUF_SIZE ((uint32_t)(AUDIO_OUT_PACKET * AUDIO_OUT_PACKET_NUM))
typedef struct
{
uint8_t cmd; 
uint8_t data[USB_MAX_EP0_SIZE]; 
uint8_t len; 
uint8_t unit; 
}
USBD_AUDIO_ControlTypeDef; 
typedef struct
{
__IO uint32_t alt_setting; 
uint8_t buffer[AUDIO_TOTAL_BUF_SIZE];
AUDIO_OffsetTypeDef offset;
uint8_t rd_enable; 
uint16_t rd_ptr; 
uint16_t wr_ptr; 
USBD_AUDIO_ControlTypeDef control; 
}
////////////////////////////////////////////////////////////////////////////////
// at usbd_conf.c
void *USBD_static_malloc(uint32_t size)
{
//static uint8_t mem[sizeof(USBD_AUDIO_HandleTypeDef)];
/* USER CODE BEGIN 4 */ 
/**
* To compute the request size you must use the formula:
AUDIO_OUT_PACKET = (USBD_AUDIO_FREQ * AUDIO_BYTES_PER_FRAME * 2) /1000)
AUDIO_TOTAL_BUF_SIZE = AUDIO_OUT_PACKET * AUDIO_OUT_PACKET_NUM with 
Number of sub-packets in the audio transfer buffer. You can modify this value but always make sure
that it is an even number and higher than 3 
AUDIO_OUT_PACKET_NUM = 80
*/ 
static uint8_t mem[512]; // fixed sized? 
/* USER CODE END 4 */
return mem;
}
////////////////////////////////////////////////////////////////////////////////
// at usbd_audio.c
static uint8_t USBD_AUDIO_Init (USBD_HandleTypeDef *pdev, 
uint8_t cfgidx)
{
USBD_AUDIO_HandleTypeDef; 
USBD_AUDIO_HandleTypeDef *haudio;
/* Open EP OUT */
USBD_LL_OpenEP(pdev,
AUDIO_OUT_EP,
USBD_EP_TYPE_ISOC,
AUDIO_OUT_PACKET);
/* Allocate Audio structure */
pdev->pClassData = USBD_malloc(sizeof (USBD_AUDIO_HandleTypeDef)); //allocate 512 byte for pClassData which should 
hold one packet
if(pdev->pClassData == NULL)
{
return USBD_FAIL; 
}
else
{
haudio = (USBD_AUDIO_HandleTypeDef*) pdev->pClassData; //??? pdev->pClassData size if 512 but cast into haudio 
which have size AUDIO_TOTAL_BUF_SIZE+77bytes ?? how does this work?
haudio->alt_setting = 0;
haudio->offset = AUDIO_OFFSET_UNKNOWN; //call to this should generate error as it is out of 512?
haudio->wr_ptr = 0; 
haudio->rd_ptr = 0; 
haudio->rd_enable = 0;
}
...
...
}

I don't understand the logic of

haudio = (USBD_AUDIO_HandleTypeDef*) pdev->pClassData;

as pdev->pClassData point to 512 bytes space while haudio is pointer toUSBD_AUDIO_HandleTypeDefwhich have size AUDIO_TOTAL_BUF_SIZE+77bytes ??

Anyone has idea how this work? and if anyone done USB audio for stm32f072 please kindly share what we should to to set different sampling rate. Thank you very much! especially reading this long post :) SG #x-cube #usb #usb #usb #audio #audio #device #device #microphone
9 REPLIES 9
tsuneo
Senior
Posted on May 20, 2016 at 20:01

The generated code of USBD_static_malloc() by CubeMX is as follows,

usbd_conf.c
// line 473
void *USBD_static_malloc(uint32_t size)
{
//static uint8_t mem[sizeof(USBD_AUDIO_HandleTypeDef)];
/* USER CODE BEGIN 4 */
/**
* To compute the request size you must use the formula:
AUDIO_OUT_PACKET = (USBD_AUDIO_FREQ * 2 * 2) /1000)
AUDIO_TOTAL_BUF_SIZE = AUDIO_OUT_PACKET * AUDIO_OUT_PACKET_NUM with
Number of sub-packets in the audio transfer buffer. You can modify this value but always make sure
that it is an even number and higher than 3
AUDIO_OUT_PACKET_NUM = 80
*/ 
static uint8_t mem[512];
/* USER CODE END 4 */
return mem;
}

As you pointed out, static uint8_t mem[512]; is wrong. The first line in this routine, static uint8_t mem[sizeof(USBD_AUDIO_HandleTypeDef)]; is the right one. Tsuneo
sgpiqx
Associate II
Posted on May 31, 2016 at 11:43

Sorry kinda late reply somehow ST forum keep saying error when I replied.

Thanks Tsuneo for your reply I managed to get USB playback work, now having difficulty adding recording path. 

After adding recording path my device seem enumerate properly, device manager shows it working properly but no playback or recording device show up. Scratching my head now, ST sample code really does not help, it built for specific board and hard to read through.

If anyone know where working STM32Fx USB audio device firmware with playback AND recording, please kindly point me. 

Btw thank you again Tsuneo, your post in PIC32 forum help me alot with HID.

tsuneo
Senior
Posted on May 31, 2016 at 18:25

> After adding recording path my device seem enumerate properly, device manager shows it working properly but no playback or recording device show up.

1) Check the descriptors

The outline of the layout is,

Config descriptor

- Interface 0 (audio control)

- - audio control header

- - input terminal (for OUT streaming)

- - output terminal (for OUT streaming)

- - feature unit (for OUT streaming)

- - input terminal (for IN streaming)

- - output terminal (for IN streaming)

- - feature unit (for IN streaming) - optional, not seen on PCM2902

- Interface 1: alt0 (audio OUT streaming) - zero-bandwidth

- Interface 1: alt1 (audio OUT streaming)

- - general descriptor

- - format type

- - endpoint iso-OUT

- - class-specific endpoint

- Interface 2: alt0 (audio IN streaming) - zero-bandwidth

- Interface 2: alt1 (audio IN streaming)

- - general descriptor

- - format type

- - endpoint iso-IN

- - class-specific endpoint

For your reference, I attached descriptor read out from PCM2902 (popular USB-audio chip)

Here are check points,

- Configuration descriptor

bNumInterfaces: 3

- audio control (AC) header,

// Audio Control Interface Header Descriptor
0x0A, // bLength // <--- (**3)
0x24, // bDescriptorType (CS_INTERFACE)
0x01, // bDescriptorSubtype (HEADER)
0x00, // bcdADC (ls byte)
0x01, // bcdADC (ms byte)
0x3E, // wTotalLength (ls byte) // <--- (**1)
0x00, // wTotalLength (ms byte)
0x02, // bInCollection
0x01, // baInterfaceNr(1)
0x02, // baInterfaceNr(2) // <--- (**2)

(**1) total bytes from AC header (this one) to the end of AC interface.

(**2) add this line for the second streaming I/F

(**3) bLength also increments by one (baInterfaceNr(2))

2) On Windows, registry still holds previous configuration, after you would change the descriptors.

- Delete (uninstall) the device instance once, if you didn't change VID/PID of the device.

or

- assign new VID/PID to the device

Tsuneo

________________

Attachments :

PCM2902_descriptors.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0es&d=%2Fa%2F0X0000000bfG%2FpiB4zSX9TjLXRkxJL4AUYO3tMaT0CgJ3_t6eqbZd_U4&asPdf=false
sgpiqx
Associate II
Posted on June 01, 2016 at 07:11

Thanks Tsuneo for the check point.

I figured out what went wrong, turn out I have miss-match terminal id and terminal link, once I sort these terminal id, PC can recognize properly.

now need to work on I2S and DMA for microphone.

Cheers!

Walid FTITI_O
Senior II
Posted on June 01, 2016 at 13:04

Hi piqx.sg,

As a reference that will help you in your application , refer to the application note done for STM32F4 ''

Audio playback and recording using the STM32F4DISCOVERY''

http://www.st.com/content/ccc/resource/technical/document/application_note/c7/2f/66/a5/cd/4c/4d/2a/DM00040802.pdf/files/DM00040802.pdf/jcr:content/translations/en.DM00040802.pdf

. The relevant firmware is found also

in

http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-embedded-software/stm32cubef4.html

at this path :

STM32Cube_FW_F4_V1.12.0\Projects\STM32F4-Discovery\Applications\Audio\Audio_playback_and_record

-Hannibal-

sgpiqx
Associate II
Posted on June 02, 2016 at 03:37

Hi Hanibal,

I have download and take a look on F4 playback and recording sample, it is useful but not really what I need as it is USB host device.

I hope ST have USB device playback and recording sample as I want to see how it managed both streaming simultaneously.

And please 24 or 32 bits as 16 bits audio is kinda outdated ;)

SG

-edit to remove quote msg

cks7788
Associate II
Posted on June 22, 2016 at 16:03

Hi guys,

Sorry that I have a dumb question

I am new to STM32's board, and we are currently using  F446 with MEMS microphone module. We want it act as a USB microphone like what it said.   http://www.st.com/content/ccc/resource/technical/document/user_manual/f5/06/94/40/a6/01/49/ae/DM00187405.pdf/files/DM00187405.pdf/jcr:content/translations/en.DM00187405.pdf

We have our USB devices code ready but when we connected to PC it shows ''unknown devices''.. That means we have to search for some other driver at PC side or it means that our code is erroneous...

Thanks for the reply

BRs,

Kevin

 

tsuneo
Senior
Posted on June 24, 2016 at 19:07

Hi Kevin,

> we are currently using F446 with MEMS microphone module.

Maybe you mean,

MEMS microphone expansion board (X-NUCLEO-CCA02M1) is mounted on NUCLEO-F446RE, instead of NUCLEO-F401RE. Also, you are running STM32F401RE-Nucleo example code in X-CUBE-MEMSMIC1 package without any change on the F446.

And then, replace C/C++ pre-defined macro in your tool chain,

from: STM32F401xE

to:   STM32F446xx

Re-compile entire project.

In this way, CCA02M1 / F446RE pair has worked on my side.

Tsuneo

Posted on June 27, 2017 at 11:04

And then, replace C/C++ pre-defined macro in your tool chain,

from: STM32F401xE

to:   STM32F446xx

Re-compile entire Project.

In this way, CCA02M1 / F446RE pair has worked on my side.

could you tell me, where exactly to Change the pre-defined macro. I'm also trying to adapt the mic aquisition code from F401RE to F446RE.

Thx,

Andreas