aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/stm32f4/src/bin/i2s_dma.rs88
1 files changed, 69 insertions, 19 deletions
diff --git a/examples/stm32f4/src/bin/i2s_dma.rs b/examples/stm32f4/src/bin/i2s_dma.rs
index 68392847b..db5103d0f 100644
--- a/examples/stm32f4/src/bin/i2s_dma.rs
+++ b/examples/stm32f4/src/bin/i2s_dma.rs
@@ -1,33 +1,83 @@
1// This example is written for an STM32F411 chip communicating with an external
2// PCM5102a DAC. Remap pins, change clock speeds, etc. as necessary for your own
3// hardware.
4//
5// NOTE: This example outputs potentially loud audio. Please run responsibly.
6
1#![no_std] 7#![no_std]
2#![no_main] 8#![no_main]
3 9
4use defmt::*;
5use embassy_executor::Spawner; 10use embassy_executor::Spawner;
6use embassy_stm32::i2s::{Config, I2S}; 11use embassy_stm32::i2s::{Config, Format, I2S};
7use embassy_stm32::time::Hertz; 12use embassy_stm32::time::Hertz;
8use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
9 14
10#[embassy_executor::main] 15#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 16async fn main(_spawner: Spawner) {
12 let p = embassy_stm32::init(Default::default()); 17 let config = {
13 info!("Hello World!"); 18 use embassy_stm32::rcc::*;
14 19
15 let mut dma_buffer = [0x00_u16; 128]; 20 let mut config = embassy_stm32::Config::default();
16 21 config.rcc.hse = Some(Hse {
17 let mut i2s = I2S::new_txonly( 22 freq: Hertz::mhz(25),
18 p.SPI2, 23 mode: HseMode::Oscillator,
19 p.PC3, // sd 24 });
20 p.PB12, // ws 25 config.rcc.pll_src = PllSource::HSE;
21 p.PB10, // ck 26 config.rcc.pll = Some(Pll {
22 p.PC6, // mck 27 prediv: PllPreDiv::DIV25,
23 p.DMA1_CH4, 28 mul: PllMul::MUL192,
29 divp: Some(PllPDiv::DIV2),
30 divq: Some(PllQDiv::DIV4),
31 divr: None,
32 });
33 config.rcc.sys = Sysclk::PLL1_P;
34
35 config.rcc.ahb_pre = AHBPrescaler::DIV1;
36 config.rcc.apb1_pre = APBPrescaler::DIV2;
37 config.rcc.apb2_pre = APBPrescaler::DIV1;
38
39 // reference your chip's manual for proper clock settings; this config
40 // is recommended for a 32 bit frame at 48 kHz sample rate
41 config.rcc.plli2s = Some(Pll {
42 prediv: PllPreDiv::DIV25,
43 mul: PllMul::MUL384,
44 divp: None,
45 divq: None,
46 divr: Some(PllRDiv::DIV5),
47 });
48 config.enable_debug_during_sleep = true;
49
50 config
51 };
52
53 let p = embassy_stm32::init(config);
54
55 // stereo wavetable generation
56 let mut wavetable = [0u16; 1200];
57 for (i, frame) in wavetable.chunks_mut(2).enumerate() {
58 frame[0] = ((((i / 150) % 2) * 2048) as i16 - 1024) as u16; // 160 Hz square wave in left channel
59 frame[1] = ((((i / 100) % 2) * 2048) as i16 - 1024) as u16; // 240 Hz square wave in right channel
60 }
61
62 // i2s configuration
63 let mut dma_buffer = [0u16; 2400];
64
65 let mut i2s_config = Config::default();
66 i2s_config.format = Format::Data16Channel32;
67 i2s_config.master_clock = false;
68 let mut i2s = I2S::new_txonly_nomck(
69 p.SPI3,
70 p.PB5, // sd
71 p.PA15, // ws
72 p.PB3, // ck
73 p.DMA1_CH7,
24 &mut dma_buffer, 74 &mut dma_buffer,
25 Hertz(1_000_000), 75 Hertz(48_000),
26 Config::default(), 76 i2s_config,
27 ); 77 );
78 i2s.start();
28 79
29 for i in 0_u16.. { 80 loop {
30 i2s.write(&mut [i * 2; 64]).await.ok(); 81 i2s.write(&wavetable).await.ok();
31 i2s.write(&mut [i * 2 + 1; 64]).await.ok();
32 } 82 }
33} 83}