embassy
embassy copied to clipboard
Support for STM32 SPDIFRX
This adds support for the STM32 SPDIFRX peripheral.
Requires https://github.com/embassy-rs/stm32-data/pull/518
This is great! Do you have a basic example of how to use it?
@kalkyl Yes, I will make one for the STM32H7 + SAI (which can use the SPDIFRX symbol clock), but the SPDIFRX feature is not yet complete.
It is missing some sort of left/right detection, otherwise left and right are randomly assigned, depending on what channel the first frame was meant for.
@kalkyl Yes, I will make one for the STM32H7 + SAI (which can use the SPDIFRX symbol clock), but the SPDIFRX feature is not yet complete.
It is missing some sort of left/right detection, otherwise left and right are randomly assigned, depending on what channel the first frame was meant for.
IIRC it's the "C" bit (channel status) in "DR", 0=left, 1=right?
The example will try to synchronize to an S/PDIF source. When it does, it outputs to SAI.
examples/stm32h723 cargo run --bin spdifrx 15s Sun Nov 3 23:40:49 2024
Compiling embassy-stm32h7-examples v0.1.0 (/home/elagil/repo/firmware-rs/embassy/examples/stm32h723)
Finished `dev` profile [optimized + debuginfo] target(s) in 0.47s
Running `probe-rs run --chip STM32H723ZGTx target/thumbv7em-none-eabihf/debug/spdifrx`
Erasing ✔ [00:00:01] [#######################################################################################################################################################################################################################################################################################################] 128.00 KiB/128.00 KiB @ 69.26 KiB/s (eta 0s )
Programming ✔ [00:00:00] [#########################################################################################################################################################################################################################################################################################################] 37.00 KiB/37.00 KiB @ 47.15 KiB/s (eta 0s ) Finished in 2.644s
DEBUG flash: latency=2 wrhighfreq=2
└─ embassy_stm32::rcc::_version::flash_setup @ /home/elagil/repo/firmware-rs/embassy/embassy-stm32/src/rcc/h.rs:1000
TRACE BDCR ok: 00008200
└─ embassy_stm32::rcc::bd::{impl#3}::init @ /home/elagil/repo/firmware-rs/embassy/embassy-stm32/src/rcc/bd.rs:198
DEBUG rcc: Clocks { csi: MaybeHertz(0), hclk1: MaybeHertz(200000000), hclk2: MaybeHertz(200000000), hclk3: MaybeHertz(200000000), hclk4: MaybeHertz(200000000), hse: MaybeHertz(0), hsi: MaybeHertz(64000000), hsi48: MaybeHertz(48000000), i2s_ckin: MaybeHertz(0), lse: MaybeHertz(0), lsi: MaybeHertz(0), pclk1: MaybeHertz(100000000), pclk1_tim: MaybeHertz(200000000), pclk2: MaybeHertz(100000000), pclk2_tim: MaybeHertz(200000000), pclk3: MaybeHertz(100000000), pclk4: MaybeHertz(100000000), pll1_q: MaybeHertz(400000000), pll2_p: MaybeHertz(0), pll2_q: MaybeHertz(0), pll2_r: MaybeHertz(0), pll3_p: MaybeHertz(0), pll3_q: MaybeHertz(0), pll3_r: MaybeHertz(0), rtc: MaybeHertz(32000), sys: MaybeHertz(400000000) }
└─ embassy_stm32::rcc::set_freqs @ /home/elagil/repo/firmware-rs/embassy/embassy-stm32/src/rcc/mod.rs:71
INFO SPDIFRX to SAI4 bridge
└─ spdifrx::____embassy_main_task::{async_fn#0} @ src/bin/spdifrx.rs:58
TRACE SPDIFRX source sync error, e.g. disconnect.
└─ spdifrx::____embassy_main_task::{async_fn#0} @ src/bin/spdifrx.rs:109
TRACE SPDIFRX source sync error, e.g. disconnect.
└─ spdifrx::____embassy_main_task::{async_fn#0} @ src/bin/spdifrx.rs:109
TRACE SPDIFRX source sync error, e.g. disconnect.
└─ spdifrx::____embassy_main_task::{async_fn#0} @ src/bin/spdifrx.rs:109
TRACE SPDIFRX source sync error, e.g. disconnect.
└─ spdifrx::____embassy_main_task::{async_fn#0} @ src/bin/spdifrx.rs:109
TRACE SPDIFRX source sync error, e.g. disconnect.
└─ spdifrx::____embassy_main_task::{async_fn#0} @ src/bin/spdifrx.rs:109
TRACE SPDIFRX source sync error, e.g. disconnect.
└─ spdifrx::____embassy_main_task::{async_fn#0} @ src/bin/spdifrx.rs:109
TRACE SPDIFRX IRQ
└─ embassy_stm32::spdifrx::{impl#5}::on_interrupt @ /home/elagil/repo/firmware-rs/embassy/embassy-stm32/src/spdifrx/mod.rs:361
TRACE SPDIFRX sync success, enable
└─ embassy_stm32::spdifrx::{impl#5}::on_interrupt::{closure#0} @ /home/elagil/repo/firmware-rs/embassy/embassy-stm32/src/spdifrx/mod.rs:374
TRACE Renew SAI.
└─ spdifrx::____embassy_main_task::{async_fn#0} @ src/bin/spdifrx.rs:115
Requires: https://github.com/embassy-rs/stm32-data/pull/535
@kalkyl Do you have some chance or hardware for testing this? I verified functionality on my STM32H723, including channel synchronization (left/right).
It makes the most sense to test this on:
- STM32H723/733
- H725/735 or
- H730
They connect the SPDIFRX symbol clock to the input of SAI4, so symbol clocks can be synchronized.
@kalkyl Do you have some chance or hardware for testing this? I verified functionality on my STM32H723, including channel synchronization (left/right).
It makes the most sense to test this on:
STM32H723/733
H725/735 or
H730
They connect the SPDIFRX symbol clock to the input of SAI4, so symbol clocks can be synchronized.
I think i only have the h750 and the h745 from the h7 family right now in the lab...
h750 and the h745
Ok, they don't have it, unfortunately. You could dump the samples into SAI regardless, with some glitches when the buffers drift apart. It would be nice to have some symbol clock output (on a pin) and then use it as the external I2S/SAI clock, but I don't think that is possible either.
Needs https://github.com/embassy-rs/embassy/pull/3511
Finally, this seems to be ready for review.
bender run
(flaky network issue...)
Thanks for working on this! Looks great to me!
Here is another example of this code in action: https://github.com/blus-audio/firmware-rs/blob/main/blus_mini_mk2/src/main.rs#L298
The data is then consumed here: https://github.com/blus-audio/firmware-rs/blob/main/blus_mini_mk2/src/audio_routing.rs#L323
There is some strangeness happening (output only 16 of 24 bit) due to me playing on four SAI slots. This is due to my hardware configuration.
I want to do some more improvements to this.. Making it a draft again.
Should be fine now. I get reliable left/right synchronization.
Making this a draft again, because playing from SPDIFRX causes some crazy side effects in my testing...
The strange behavior was resolved.
I used the SPDIFRX symbol clock to drive SAI, and once SPDIF was disconnected, there was no way to switch SAI clock sources again. Therefore, backup symbol clock had to be enabled to help with that.
bender run
bender run
bender run