cancel
Showing results for 
Search instead for 
Did you mean: 

USB Audio Device Class usage clarification

Christopher Pappas
Senior II
Posted on February 19, 2018 at 14:19

In my attempt to create a BSP Audio Driver for Nucleo boards, I am having difficulty visualizing how to get data out of the incoming audio packets.

Currently in my project, I am guessing where the audio buffers are located (by watching the memory for a block of data that changes every 1ms with the length 0x3E00) since I can't get that info out of the local 

USB Audio Device. Once I guess it, I set my DAC double-buffered DMA Audio to this address to play the data out thru the internal 12-bit DAC.

Obviously, it is a ridiculous way to code since every time I re-compile the code, the buffer location is different. Also, since I have no way of sensing where the read and write pointers are pointing to in the buffer, it is hard to synchronize the incoming data to the speed of the DMA transfers. The results is that the audio plays, but very erratically.

The USB Audio Device structures and variables seem to be local only. I'm assuming it is because the code has been written in HAL.

How could I get to the data from within my main program (I.E. - USB Audio Buffer Location Address, Read Pointer, Write Pointer, etc).

Any Ideas, comments, or suggestions would be greatly appreciated!

Thanks!

Christopher

#usb-audio #stm32-audio-usb #nucleo-f767zi #usb-audio-device-class
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on February 19, 2018 at 15:33

The buffer itself is allocated dynamically, together with the pointers/indices, in USBD_AUDIO_Init() in [STM32_USB_Device_Library]\Class\AUDIO\Src\usbd_audio.c

  /* Allocate Audio structure */

  pdev->pClassData = USBD_malloc(sizeof (USBD_AUDIO_HandleTypeDef));

where

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;   

}

USBD_AUDIO_HandleTypeDef;

So the buffer is accessible through pdev->pClassData, typecast to USBD_AUDIO_HandleTypeDef*.

But you as a user are not supposed to be bothered by the implementation details of such a grand library; you are supposed to supply the consumer function through  a function, address of which is then filled into AudioCmd field of a struct of USBD_AUDIO_ItfTypeDef type, pointer to which is supplied to USBD_AUDIO_RegisterInterface(). AudioCmd() is called back from the whole stack with a data pointer and size (and a command byte), and you are supposed to consume the data in that function.

JW

View solution in original post

1 REPLY 1
Posted on February 19, 2018 at 15:33

The buffer itself is allocated dynamically, together with the pointers/indices, in USBD_AUDIO_Init() in [STM32_USB_Device_Library]\Class\AUDIO\Src\usbd_audio.c

  /* Allocate Audio structure */

  pdev->pClassData = USBD_malloc(sizeof (USBD_AUDIO_HandleTypeDef));

where

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;   

}

USBD_AUDIO_HandleTypeDef;

So the buffer is accessible through pdev->pClassData, typecast to USBD_AUDIO_HandleTypeDef*.

But you as a user are not supposed to be bothered by the implementation details of such a grand library; you are supposed to supply the consumer function through  a function, address of which is then filled into AudioCmd field of a struct of USBD_AUDIO_ItfTypeDef type, pointer to which is supplied to USBD_AUDIO_RegisterInterface(). AudioCmd() is called back from the whole stack with a data pointer and size (and a command byte), and you are supposed to consume the data in that function.

JW