Closed Dicklessgreat closed 1 month ago
If you are testing this, my own implementation is for STM32H723: https://github.com/blus-audio/firmware-rs See especially https://github.com/blus-audio/firmware-rs/blob/main/firmware/src/usb_audio.rs
It requires this, though: https://github.com/embassy-rs/stm32-data/pull/511 Otherwise, the USB_SOF signal is not available on the timer, because it uses the wrong set of registers. You have to check, which timers actually have the USB_SOF signal available to them, it could be that TIM2 is the only one.
Thanks for your answer. I did:
git clone https://github.com/elagil/stm32-data.git
cd stm32-data
git switch fix_stm32h7_timer_versions
./d download-all
cargo run --release --bin stm32-data-gen
cargo run --release --bin stm32-metapac-gen
git clone https://github.com/elagil/embassy
cd embassy
git switch feat_usb_prepare_for_uac
embassy/embassy-stm32/Cargo.toml
to specify the local stm32-metapac
, likestm32-metapac = { path = "../../stm32-data/build/stm32-metapac" }
daisy_embassy/Cargo,toml
to specify the local embassy (see my previous commit)cargo build
then...
Compiling stm32-metapac v15.0.0 (/Users/dicklessgreat/Documents/Rust/_third_party/stm32-data/build/stm32-metapac)
rustc-LLVM ERROR: Global variable '__INTERRUPTS' has an invalid section specifier '.vector_table.interrupts': mach-o section specifier requires a segment and section separated by a comma.
error: could not compile `stm32-metapac` (lib)
Do you have any ideas what this error means? Thanks.
That looks exactly like what I was doing. It seems to not find that vector table section in your linker file, but I don't know why that would be the case. Is it building for the right target (arm)?
You don't have to use my stm32-data
if you don't enable feedback. It's fine to run without feedback, but you will get an occasional glitch. Maybe that is a g good first step?
An unrelated thing in your Cargo.toml
: you cannot use time-driver-tim2
if you want to use it as the feedback timer. I guess that's why you switched the feedback timer to tim5.
It is for the right target, I think, I have run examples with this settings for many times.
If I do comment out specifying local metapac and comment in as embassy do in embassy/embassy-stm32/Cargo.toml
, I mean...:
stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-e0cfd165fd8fffaa0df66a35eeca83b228496645" }
# stm32-metapac = { path = "../../stm32-data/build/stm32-metapac" }
then it is buildable...
But anyway, I'll try the "good first step" later! Thanks!
If i remember correctly, I had to change the metapac in two places in the Cargo.toml
, but maybe you already did.
Good luck!
OK, now my Windows recognizes the device as a "speaker"! I haven't checked if it really sounds well or not. I'll try again tomorrow!
current status: It is now possible to receive audio from the host and output what appears to be that audio through the SAI. But as expected, it does not works well, because audio buffer from USB is exhausted while SAI is running, which makes short "glitches" to the output audio(if I understand correctly).
I'll check if the passing audio buffer from USB task to audio receiver really works (I'll check the detail of blus-audio
's firmware).
And after that, I'll try patched metapac , but I have to tuckle the error: rustc-LLVM ERROR: Global variable '__INTERRUPTS' has an invalid section specifier '.vector_table.interrupts'
I found this and tried [workspace]
resolver="2"
, but same error.
https://github.com/embassy-rs/embassy/issues/1165
I don't know where this error comes from...
Not sure about the build issue, because I am not using a workspace.
Regarding the glitches, that is expected without active feedback, because the rates of receiving and consuming don't match. For transferring data between the USB streaming task and the SAI task, I had good results with a zerocopy-channel. You will find that in the blus-audio firmware, or in the example that I wrote for embassy (STM32F4).
It turns out that rustc-LLVM ERROR
comes from I missed to add default-features = false, features = ["metadata"]
to the stm32-metapac
in [build-dependencies]
of the local embassy-stm32/Cargo.toml
.
OUCH!!
from RM0433 "Reference Manual" P.1682 Table338 (STM32H742, STM32H743/753 and STM32H750 Value line advanced Arm ® -based 32-bit MCUs)
There are still glitches in output audio from SAI.
I found use_feedback_task
infinitely do await for the connection.
So feedback not yet works.
Hmm, I have no idea to solve.
Do you have any ideas? @elagil
I checked TIM2 interrupt and control task is working(by adding info!
macro and checking defmt
output).
sampling rate of SAI: 48000Hz
audio block length: 32(samples per channel)
That is strange. Are you on Windows or Linux? If the latter, can you show lsusb -d 0xdead:0xbeef -v
for me to check if the descriptors are correct?
You may also look at dmesg
, it can give hints for issues with the USB device.
Regarding the audio block length, I don't quite understand. You will get blocks of (around) 1 ms of stereo samples at 48 kHz, which is 48 (stereo) samples per ms -> 384 byte. You may get even more samples than that when the feedback mechanism indicates a consumption rate above 48 kHz. So, you should probably allow for a bigger audio block length.
Then, you are only allowing for a timeout of 500 micro seconds for receiving samples in the audio_receiver_task
. Samples in USB full-speed arrive at a fixed spacing of 1 ms, so that will not work. You should allow for maybe 2 ms of timeout - but definitely more than 1 ms.
Thanks for your feedback!
Sorry, I missed some logs from debug probe.
Let me correct current state. The feedback is properly connected, but endpoint is stucked. So the feedback loop infinitely await at the second loop of feedback.write_packet(&packet).await?;
here.
I don't know how feedback should work but I think feedback should be periodically feed to host during the playback, right?
I'm using Windows.
So I did usbipd wsl attach --busid x-x
on Windows Power Shell to pass the device to WSL, and did the command you suggested.
lsusb -d 0xdead:0xbeef -v
Bus 001 Device 002: ID dead:beef Embassy USB-audio-speaker example
Couldn't open device, some information will be missing
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.10
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0xdead
idProduct 0xbeef
bcdDevice 0.10
iManufacturer 1
iProduct 2
iSerial 3
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x007f
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 100mA
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 0
bInterfaceCount 2
bFunctionClass 1 Audio
bFunctionSubClass 1 Control Device
bFunctionProtocol 0
iFunction 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 1 Control Device
bInterfaceProtocol 0
iInterface 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 1.00
wTotalLength 0x0028
bInCollection 1
baInterfaceNr(0) 1
AudioControl Interface Descriptor:
bLength 12
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0101 USB Streaming
bAssocTerminal 0
bNrChannels 2
wChannelConfig 0x0003
Left Front (L)
Right Front (R)
iChannelNames 0
iTerminal 0
AudioControl Interface Descriptor:
bLength 10
bDescriptorType 36
bDescriptorSubtype 6 (FEATURE_UNIT)
bUnitID 2
bSourceID 1
bControlSize 1
bmaControls(0) 0x00
bmaControls(1) 0x03
Mute Control
Volume Control
bmaControls(2) 0x03
Mute Control
Volume Control
iFeature 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 3
wTerminalType 0x0301 Speaker
bAssocTerminal 0
bSourceID 2
iTerminal 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 1
bNumEndpoints 2
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
AudioStreaming Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 1
bDelay 0 frames
wFormatTag 0x0001 PCM
AudioStreaming Interface Descriptor:
bLength 11
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bNrChannels 2
bSubframeSize 4
bBitResolution 32
bSamFreqType 1 Discrete
tSamFreq[ 0] 48000
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0300 1x 768 bytes
bInterval 1
bRefresh 0
bSynchAddress 129
AudioStreaming Endpoint Descriptor:
bLength 7
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x01
Sampling Frequency
bLockDelayUnits 2 Decoded PCM samples
wLockDelay 0x0000
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 17
Transfer Type Isochronous
Synch Type None
Usage Type Feedback
wMaxPacketSize 0x0004 1x 4 bytes
bInterval 1
bRefresh 3
bSynchAddress 0
dmesg | grep usb(and omit some unrelevant messages)
[ 51.505104] usb 1-1: new full-speed USB device number 2 using vhci_hcd
[ 51.855109] usb 1-1: SetAddress Request (2) to port 0
[ 52.084792] usb 1-1: not running at top speed; connect to a high speed hub
[ 52.173119] usb 1-1: New USB device found, idVendor=dead, idProduct=beef, bcdDevice= 0.10
[ 52.173124] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 52.173132] usb 1-1: Product: USB-audio-speaker example
[ 52.173136] usb 1-1: Manufacturer: Embassy
[ 52.173139] usb 1-1: SerialNumber: 12345678
BTW, the dmesg
results reminded me that your example on the STM32F4 was USB "FS", and blus-audio was doing USB "HS". Although your main field is "HS", you would assume this example works with USB FS, right? (Daisy Seed has only a USB FS port.) I ask just for the confirmation!:)
And about audio callback, sorry I didn't clearly say I'm suspicious about my current settings(that's why I wrote it). But your answer really hits what I want to ask! Thanks. I'll try fix after my works! I'll be back after finishing my daily tasks.
In relation to other committers' PRs, I will close this PR for now, but I plan to open a new issue and reopen it at a later time.
@Dicklessgreat I didn't see your high-speed vs. full-speed question. This is only expected to work correctly with full-speed USB, as UAC 1.0 is specified for USB 1.0/1.1.
In fact, I use my HS phy in FS mode.
In fact, I use my HS phy in FS mode.
I didn't know that's possible! And I missed it's in FS mode.
I didn't see your high-speed vs. full-speed question.
Never mind! Just I wondered if it really works on my device!
Let me correct current state. The feedback is properly connected, but endpoint is stucked. So the feedback loop infinitely await at the second loop of feedback.write_packet(&packet).await?; here.
And do you have any ideas about this?
Not yet commited but in local, I tried to expand SAI callback length, and to expand zerocopy
's timeout period to 2ms, but had no luck.
Thanks
I didn't know that's possible! And I missed it's in FS mode.
It is, as of recently :smile:: https://github.com/embassy-rs/embassy/pull/3281 I had to add support for it, because it didn't work correctly on Windows in high-speed mode. I am not sure why.
And do you have any ideas about this?
Are you sure it's stuck there and not waiting for the signal? I don't know why it would get stuck, except if the host doesn't poll the endpoint. I will test on Windows again.
from https://github.com/embassy-rs/embassy/pull/3212 and https://github.com/elagil/embassy/blob/feat_usb_prepare_for_uac/examples/stm32f4/src/bin/usb_uac_speaker.rs
changes from STM32F4 example:
hal::Config
todaisy_embassy::default_rcc()
not yet works, just quick trying it out for a bit.