Test project for a composite audio and USB UART for STM32H723. It merges parts of the UAC2_Headset and CDC_MSC examples. The examples that come with TinyUSB have a loopback for CDC. A greeting message had been added. UAC2 had a audio loopback feature, now a 432 Hz sine wave is generated, to show how to emit audio. Set microphone device at 16 bit, 48000 kHz, the only supported conficuration. Porting to a new STM32H device should be easy:
- Start a new project for your MCU of choice.
- configure clocks as needed with the graphical tool. USB clock should be 48 MHz.
- set RCC for crystal or oscillator.
- set Timebase Souce in SYS to SysTick.
- enable USB OTG as internal FS, device only, in Connectivity. Enable global interrupt for USB OTG HS.
- Configure the rest of your peripherals.
- Generate code, then merge thne files from this example. TinyUSB part can be copied in the new project. The new main.c has code that was generated by STM32Cube. Add the parts that are specific to this application. Maybe in a future release this code will be moved to a separate file, to make things easier.
- Set the include and source location in project properties as in this example. Have a look at the errors and warnings should the build fail.
- Hardware configuration is performed by STM32Cube, the bsp part of TinyUSB is irrilevant in this case. Files are still left in the project, for reference.
You should be done with this, YMMV, as of today the TinyUSB library is not really documented.
Some advice:
If the USB descriptors are changed, better change the serial number of the device, or the host OS will use a not updated, cached configuration for it and all kind of strange behaviour will drive you insane.
Sometimes a clean build is required to solve some misterious issue.
Wireshark with USB sniffing plugin could give some hint on what's going on.
It seems that TinyUSB supports different buffers mechanisms for IO. Not clear how they can be used and there are no examples for this. For now audio data is injected in the tud_audio_tx_done_pre_load_cb. This callback is executed at 1000 Hz and must be filled exactly with the amount of data that it consumes. In this case, 48K / 1000 = 48 samples, 16 bit each.
As of today, in spite of these limits, this is still the easiest way for composite devices, free of charge obviously.