Skip to content

Commit 6602ddf

Browse files
authored
Merge pull request #684 from algesten/feature/dual-i2s-dma
Enable DMA for DualI2sDriver main() and ext() respectively
2 parents 24534da + 0c004ca commit 6602ddf

File tree

3 files changed

+83
-3
lines changed

3 files changed

+83
-3
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
on:
22
push:
3-
branches: master
3+
branches: ["master"]
44
pull_request:
55
merge_group:
66

CHANGELOG.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,32 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
### Changed
11+
1012
- add trait bound `RegisterBlockImpl` to type `RegisterBlock` associated with `serial::Instance` [#732]
1113
- remove unneeded trait bound for methods that take in a `serial::Instance` and use the associated `RegisterBlock`
1214
- bump `sdio-host` to 0.9.0, refactor SDIO initialization [#734]
1315
- Added non-blocking serial based on DMA [#738]
1416
- use RTCCLK for RTC wakeup timer for short durations [#746]
17+
- Enable DMA for DualI2sDriver main() and ext() respectively [#684]
1518
- Support 8-bit FMC data bus
16-
- Port `rtic-time::Monotonic` implementations from `rtic-monotonics` for TIMx
19+
- Port `rtic-time::Monotonic` implementations from `rtic-monotonics` for TIMx [#756]
1720

1821
### Fixed
1922

2023
- Fix transmission termination in I2C master DMA read [#736]
2124
- Prevent starting a new I2C transmission before previous stop finishes [#737]
2225
- Fix complementary output polarity for PWM [#754]
2326

27+
[#684]: https://github.com/stm32-rs/stm32f4xx-hal/pull/684
28+
[#732]: https://github.com/stm32-rs/stm32f4xx-hal/pull/732
29+
[#734]: https://github.com/stm32-rs/stm32f4xx-hal/pull/734
30+
[#736]: https://github.com/stm32-rs/stm32f4xx-hal/pull/736
31+
[#737]: https://github.com/stm32-rs/stm32f4xx-hal/pull/737
32+
[#738]: https://github.com/stm32-rs/stm32f4xx-hal/pull/738
33+
[#746]: https://github.com/stm32-rs/stm32f4xx-hal/pull/746
34+
[#756]: https://github.com/stm32-rs/stm32f4xx-hal/pull/756
35+
2436
## [v0.20.0] - 2024-01-14
2537

2638
### Changed

src/i2s.rs

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,12 @@ dual_i2s!(pac::SPI3, pac::I2S3EXT, DualI2s3, i2s3, i2s_apb1_clk);
449449
mod dma {
450450
use super::*;
451451
use crate::dma::traits::{DMASet, PeriAddress};
452+
use crate::pac::spi1::RegisterBlock;
453+
use core::marker::PhantomData;
452454
use core::ops::Deref;
453-
use stm32_i2s_v12x::driver::I2sDriver;
455+
use stm32_i2s_v12x::driver::{I2sCore, I2sDriver};
456+
use stm32_i2s_v12x::transfer::{Ext, Main};
457+
use stm32_i2s_v12x::DualI2sPeripheral;
454458

455459
/// I2S DMA reads from and writes to the data register
456460
unsafe impl<SPI: Instance, MS, TR, STD> PeriAddress for I2sDriver<I2s<SPI>, MS, TR, STD>
@@ -474,4 +478,68 @@ mod dma {
474478
SPI: DMASet<STREAM, CHANNEL, DIR>,
475479
{
476480
}
481+
482+
pub trait DualI2sDmaTargetExt<I, PART, MS, DIR, STD> {
483+
fn dma_target(&self) -> DualI2sDmaTarget<I, PART, MS, DIR, STD>;
484+
}
485+
impl<I, PART, MS, DIR, STD> DualI2sDmaTargetExt<I, PART, MS, DIR, STD>
486+
for I2sCore<I, PART, MS, DIR, STD>
487+
{
488+
fn dma_target(&self) -> DualI2sDmaTarget<I, PART, MS, DIR, STD> {
489+
DualI2sDmaTarget {
490+
_dual_i2s_peripheral: PhantomData,
491+
_part: PhantomData,
492+
_ms: PhantomData,
493+
_dir: PhantomData,
494+
_std: PhantomData,
495+
}
496+
}
497+
}
498+
499+
/// - `I`: The [DualI2sPeripheral] controlled by the I2sCore.
500+
/// - `PART`: `Main` or `Ext`. The part of [DualI2sPeripheral] controlled by I2sCore.
501+
/// - `MS`: `Master` or `Slave`. The role of the I2sCore. Only a `Main` I2sCore can be Master.
502+
/// - `DIR` : `Transmit` or `Receive`. Communication direction.
503+
/// - `STD`: I2S standard, eg `Philips`
504+
pub struct DualI2sDmaTarget<I, PART, MS, DIR, STD> {
505+
_dual_i2s_peripheral: PhantomData<I>,
506+
_part: PhantomData<PART>,
507+
_ms: PhantomData<MS>,
508+
_dir: PhantomData<DIR>,
509+
_std: PhantomData<STD>,
510+
}
511+
512+
macro_rules! dual_dma {
513+
($ext: ty, $reg: ident) => {
514+
/// I2S DMA reads from and writes to the data register
515+
unsafe impl<SPIext: DualInstance, MS, TR, STD> PeriAddress
516+
for DualI2sDmaTarget<DualI2s<SPIext>, $ext, MS, TR, STD>
517+
where
518+
DualI2s<SPIext>: DualI2sPeripheral,
519+
{
520+
/// SPI_DR is only 16 bits. Multiple transfers are needed for a 24-bit or 32-bit sample,
521+
/// as explained in the reference manual.
522+
type MemSize = u16;
523+
524+
fn address(&self) -> u32 {
525+
let reg = unsafe { &*(DualI2s::$reg as *const RegisterBlock) };
526+
(&reg.dr) as *const _ as u32
527+
}
528+
}
529+
};
530+
}
531+
532+
dual_dma!(Main, MAIN_REGISTERS);
533+
dual_dma!(Ext, EXT_REGISTERS);
534+
535+
/// DMA is available for I2S based on the underlying implementations for SPI
536+
unsafe impl<SPIext: DualInstance, PART, MS, TR, STD, STREAM, const CHANNEL: u8, DIR>
537+
DMASet<STREAM, CHANNEL, DIR> for DualI2sDmaTarget<DualI2s<SPIext>, PART, MS, TR, STD>
538+
where
539+
SPIext: DMASet<STREAM, CHANNEL, DIR>,
540+
{
541+
}
477542
}
543+
544+
#[cfg(feature = "stm32_i2s_v12x")]
545+
pub use dma::{DualI2sDmaTarget, DualI2sDmaTargetExt};

0 commit comments

Comments
 (0)