Skip to content

Commit a7f6bea

Browse files
committed
Initial
0 parents  commit a7f6bea

34 files changed

+5703
-0
lines changed

.gitignore

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
target
2+
Cargo.lock
3+
4+
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
5+
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
6+
7+
# User-specific stuff
8+
.idea/**/workspace.xml
9+
.idea/**/tasks.xml
10+
.idea/**/usage.statistics.xml
11+
.idea/**/dictionaries
12+
.idea/**/shelf
13+
14+
# Generated files
15+
.idea/**/contentModel.xml
16+
17+
# Sensitive or high-churn files
18+
.idea/**/dataSources/
19+
.idea/**/dataSources.ids
20+
.idea/**/dataSources.local.xml
21+
.idea/**/sqlDataSources.xml
22+
.idea/**/dynamic.xml
23+
.idea/**/uiDesigner.xml
24+
.idea/**/dbnavigator.xml
25+
26+
# Gradle
27+
.idea/**/gradle.xml
28+
.idea/**/libraries
29+
30+
# Gradle and Maven with auto-import
31+
# When using Gradle or Maven with auto-import, you should exclude module files,
32+
# since they will be recreated, and may cause churn. Uncomment if using
33+
# auto-import.
34+
# .idea/artifacts
35+
# .idea/compiler.xml
36+
# .idea/jarRepositories.xml
37+
# .idea/modules.xml
38+
# .idea/*.iml
39+
# .idea/modules
40+
# *.iml
41+
# *.ipr
42+
43+
# CMake
44+
cmake-build-*/
45+
46+
# Mongo Explorer plugin
47+
.idea/**/mongoSettings.xml
48+
49+
# File-based project format
50+
*.iws
51+
52+
# IntelliJ
53+
out/
54+
55+
# mpeltonen/sbt-idea plugin
56+
.idea_modules/
57+
58+
# JIRA plugin
59+
atlassian-ide-plugin.xml
60+
61+
# Cursive Clojure plugin
62+
.idea/replstate.xml
63+
64+
# Crashlytics plugin (for Android Studio and IntelliJ)
65+
com_crashlytics_export_strings.xml
66+
crashlytics.properties
67+
crashlytics-build.properties
68+
fabric.properties
69+
70+
# Editor-based Rest Client
71+
.idea/httpRequests
72+
73+
# Android studio 3.1+ serialized cache file
74+
.idea/caches/build_file_checksums.ser

.idea/.gitignore

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/stm32_i2s.iml

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
[package]
2+
name = "stm32_i2s"
3+
version = "0.1.0"
4+
authors = ["Sam Crow <[email protected]>"]
5+
edition = "2018"
6+
description = "Driver for the SPI peripherals (in I2S mode) for some STM32 microcontrollers"
7+
license = "0BSD"
8+
repository = "https://github.com/samcrow/stm32_i2s"
9+
# Build script for examples only
10+
build = "build.rs"
11+
12+
[dependencies]
13+
vcell = "0.1.3"
14+
nb = "1.0.0"
15+
16+
# Dependencies for examples
17+
[dev-dependencies]
18+
cortex-m-rt = "0.6.13"
19+
nb = "1.0.0"
20+
21+
[dev-dependencies.rtt-target]
22+
version = "0.3.0"
23+
features = ["cortex-m"]
24+
25+
[dev-dependencies.panic-rtt-target]
26+
version = "0.1.1"
27+
features = ["cortex-m"]
28+
29+
# Needs an unreleased version to set up the I2S clocks correctly
30+
[dev-dependencies.stm32f4xx-hal]
31+
git = "https://github.com/stm32-rs/stm32f4xx-hal"
32+
rev = "1f0385fec243693537750b5baee2ac7d1dbc06e7"
33+
features = ["stm32f412", "rt"]

Embed.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# cargo-embed configuration file for running the examples
2+
[default.general]
3+
chip = "STM32F412VGTx"
4+
5+
[default.rtt]
6+
enabled = true

LICENSE.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Copyright (C) 2021 by Sam Crow
2+
3+
Permission to use, copy, modify, and/or distribute this software for any
4+
purpose with or without fee is hereby granted.
5+
6+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
7+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
8+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
9+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
10+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
11+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
12+
PERFORMANCE OF THIS SOFTWARE.

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# STM32 I2S driver
2+
3+
This library provides a driver for I2S communication using the SPI peripherals on some STM32 microcontrollers.
4+
5+
## Differences between STM32 models
6+
7+
According to application note [AN5543](https://www.st.com/resource/en/application_note/dm00725181-enhanced-methods-to-handle-spi-communication-on-stm32-devices-stmicroelectronics.pdf),
8+
there are four major versions of the SPI/I2S peripheral used on STM32 microcontrollers:
9+
10+
* 1.2.x: F1, F2, F4, L0, L1
11+
* 1.3.x: F0, F3, F7, L4, L5, WB, WL
12+
* 2.x.x: H7, MP1
13+
* 3.x.x: "Most of STM32 devices launched in 2021 or later"
14+
15+
This library currently has code for SPI version 1.2 (STM32F1, STM32F2, STM32F4, STM32L0, and STM32L1).
16+
17+
## Status
18+
19+
This library has been tested on a few different STM32F4 microcontrollers. The
20+
other models that use the same SPI version (F1, F2, L0, and L1) may work,
21+
but I have not tested any of them.
22+
23+
## License
24+
25+
0-clause BSD (see LICENSE.txt)

build.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//! This build script is only needed for the examples. When just building the library,
2+
//! it still runs but should have no effect.
3+
4+
use std::env;
5+
use std::fs::File;
6+
use std::io::Write;
7+
use std::path::PathBuf;
8+
9+
fn main() {
10+
// Put the linker script somewhere the linker can find it
11+
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
12+
File::create(out.join("memory.x"))
13+
.unwrap()
14+
.write_all(include_bytes!("memory.x"))
15+
.unwrap();
16+
println!("cargo:rustc-link-search={}", out.display());
17+
18+
// Only re-run the build script when memory.x is changed,
19+
// instead of when any part of the source code changes.
20+
println!("cargo:rerun-if-changed=memory.x");
21+
}

examples/master_transmit_d16f16.rs

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
//!
2+
//! Periodically transmits a sequence of 16-bit samples using SPI1/I2S1 on an STM32F412
3+
//!
4+
//! Pins:
5+
//! * PA4, AF5 - I2S1_WS
6+
//! * PA5, AF5 - I2S1_CK
7+
//! * PA7, AF5 - I2S1_SD
8+
//!
9+
//! To compile:
10+
//! RUSTFLAGS="-C link-arg=-Tlink.x" cargo build --example master_transmit_d16f16 --target thumbv7em-none-eabihf --release
11+
//!
12+
//! This uses some unsafe code so that it can depend on a version of stm32f4xx-hal that does not
13+
//! depend on stm32_i2s.
14+
//!
15+
16+
#![no_std]
17+
#![no_main]
18+
19+
extern crate cortex_m_rt;
20+
extern crate nb;
21+
extern crate panic_rtt_target;
22+
extern crate rtt_target;
23+
extern crate stm32_i2s;
24+
extern crate stm32f4xx_hal;
25+
26+
use stm32f4xx_hal::hal::prelude::*;
27+
use stm32f4xx_hal::pac::{CorePeripherals, Peripherals};
28+
use stm32f4xx_hal::prelude::*;
29+
use stm32f4xx_hal::timer::Timer;
30+
31+
use stm32_i2s::v12x::format::{Data16Frame16, FrameFormat};
32+
use stm32_i2s::v12x::{I2s, Instance, MasterConfig, RegisterBlock};
33+
use stm32_i2s::Polarity;
34+
35+
/// 16-bit samples to transmit
36+
const TEST_SAMPLES: [i16; 12] = [
37+
0x0000,
38+
0x0000,
39+
0xaa55_u16 as i16,
40+
0x55aa_u16 as i16,
41+
0x0000_u16 as i16,
42+
0xffff_u16 as i16,
43+
0x1010_u16 as i16,
44+
0xaaaa_u16 as i16,
45+
0x5555_u16 as i16,
46+
0xe621_u16 as i16,
47+
0x0000,
48+
0x0000,
49+
];
50+
51+
/// Sample rates to test
52+
const SAMPLE_RATES: [u32; 8] = [8000, 16000, 22050, 32000, 44100, 48000, 96000, 192000];
53+
54+
#[cortex_m_rt::entry]
55+
fn main() -> ! {
56+
let cp = CorePeripherals::take().unwrap();
57+
let dp = Peripherals::take().unwrap();
58+
// RTT for logging
59+
rtt_target::rtt_init_print!();
60+
61+
let rcc = dp.RCC.constrain();
62+
// SPI1/I2S1 is on APB2
63+
let clocks = rcc
64+
.cfgr
65+
.sysclk(100.mhz())
66+
.i2s_apb1_clk(38400.khz())
67+
.i2s_apb2_clk(38400.khz())
68+
.freeze();
69+
70+
// Use systick to run periodically
71+
let mut systick = Timer::syst(cp.SYST, 1000.hz(), clocks);
72+
73+
let gpioa = dp.GPIOA.split();
74+
let _i2s_pins = (
75+
gpioa.pa4.into_alternate_af5(),
76+
gpioa.pa5.into_alternate_af5(),
77+
gpioa.pa7.into_alternate_af5(),
78+
);
79+
let mut sync_pin = gpioa.pa1.into_push_pull_output();
80+
sync_pin.set_low().unwrap();
81+
82+
// Access the RCC registers directly to enable SPI1
83+
unsafe {
84+
let rcc_registers = stm32f4xx_hal::pac::RCC::ptr();
85+
(*rcc_registers).apb2enr.modify(|_, w| w.spi1en().enabled());
86+
}
87+
88+
let mut i2s = I2s::new(I2s1Substitute);
89+
90+
loop {
91+
for &sample_rate in SAMPLE_RATES.iter() {
92+
let config = MasterConfig::with_sample_rate(
93+
clocks.i2s_apb2_clk().unwrap().0,
94+
sample_rate,
95+
Data16Frame16,
96+
FrameFormat::PhilipsI2s,
97+
Polarity::IdleHigh,
98+
false,
99+
);
100+
let mut configured_i2s = i2s.configure_master_transmit(config);
101+
102+
configured_i2s.enable();
103+
configured_i2s.transmit_blocking(&TEST_SAMPLES);
104+
nb::block!(configured_i2s.disable()).unwrap();
105+
106+
i2s = configured_i2s.deconfigure();
107+
108+
nb::block!(systick.wait()).unwrap();
109+
}
110+
sync_pin.toggle().unwrap();
111+
}
112+
}
113+
114+
struct I2s1Substitute;
115+
116+
unsafe impl Instance for I2s1Substitute {
117+
const REGISTERS: *mut RegisterBlock = stm32f4xx_hal::pac::SPI1::ptr() as *mut RegisterBlock;
118+
}

0 commit comments

Comments
 (0)