Skip to content

Enable full-duplex I2S for spi_v2 devices using I2SEXT peripherals#5773

Draft
bifurcation wants to merge 3 commits intoembassy-rs:mainfrom
link-rs:main
Draft

Enable full-duplex I2S for spi_v2 devices using I2SEXT peripherals#5773
bifurcation wants to merge 3 commits intoembassy-rs:mainfrom
link-rs:main

Conversation

@bifurcation
Copy link
Copy Markdown

Fixes #4698

There are two classes of changes in this PR: Ones that will be permanent, and ones that are temporary until stm32-metapac gets updated to reflect information about I2SEXT peripherals.

Changes of the latter type are reflected in a few traits at the top of the file. I have mimicked traits such as WsPin and RxDma, which is nice because it preserves a bunch of the design patterns below. It seems like metapac just needs to add these traits and implement them as appropriate for a device, but I don't grok metapac well enough to make this change right now. The I2sRegs trait should probably be absorbed into spi::Instance.

The permanent changes are of the following character:

  • We add a method I2S::new_full_duplex() which is feature-gated to spi_v2 (though TBH I'm not sure if this is the only version of SPI that should be covered, or if every spi_v2 platform has I2SEXT peripherals)
  • We add a field to struct I2S to hold the register block for the I2SEXT peripheral, if used
  • In new_inner, if an I2SEXT peripheral is being used, we initialize it to the same I2S settings as the main SPI peripheral, in the opposite direction, and always in slave mode.
  • Instead of referring to a single register block self.spi.info.regs, we distinguish between register blocks used in the tx and rx directions. These are different when an I2SEXT peripheral is in use, and the same otherwise. This does result in some duplication when I2SEXT is not in use; it might be possible to refactor to avoid.

Marking this as draft because of the above-mentioned issues, and because of the unresolved dependency on metapac changes. I have tested this on a real device using stm32f405rg using SPI to talk to an WM8960 and it works reliably, but I have not tested not more generally.

Replaces #4746

bifurcation and others added 3 commits February 20, 2026 14:02
The STM32F4 SPI2/SPI3 peripherals have associated I2SEXT peripherals
(I2S2EXT/I2S3EXT) that enable true full-duplex I2S. These are not in
stm32-metapac, so we define custom traits for the SPI-to-I2SEXT register
mapping, DMA request numbers, and AF pin assignments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add I2SEXT peripheral traits (I2sExtRegs, RxDmaExt, SdExtPin) for
  STM32F405 SPI2/SPI3
- Add new_full_duplex constructor for spi_v2 using I2SEXT
- Add regs_tx/regs_rx helpers and read_write method
- Update start/stop to handle I2SEXT peripheral enable/disable
- Configure I2SEXT in new_inner with opposite direction and slave mode
- RX DMA reads from I2SEXT register block when present
- Rename existing spi_v3 full_duplex to new_full_duplex_native
- Enable I2S (set_i2se) in start() for spi_v1/v2/v3

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The I2SEXT-based full-duplex method works on both spi_v1 (STM32F405 in
embassy 0.4) and spi_v2 (embassy 0.5). Widen the cfg gate so the
constructor is available on both.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@bifurcation
Copy link
Copy Markdown
Author

This PR is also based on an older commit of embassy-stm32, so it probably needs a fairly substantial rebase.

@xoviat
Copy link
Copy Markdown
Contributor

xoviat commented Apr 2, 2026

@bifurcation hang on a minute, I'm going to rework the traits a bit...

@bifurcation
Copy link
Copy Markdown
Author

@xoviat No rush! My fork is working for me right now, so we can do thus on whatever schedule you like. I just refreshed the PR with my latest state since I saw your ping.

@xoviat xoviat mentioned this pull request Apr 2, 2026
@xoviat
Copy link
Copy Markdown
Contributor

xoviat commented Apr 2, 2026

@bifurcation I just merged #5774, which should have the traits that you need to complete this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enable "dual" full-duplex I2S for "v2_i2s" devices

2 participants