Skip to content

Commit e63a34b

Browse files
committed
stm32/sdmmc: add hil test for f4.
1 parent 82dd7a5 commit e63a34b

File tree

3 files changed

+234
-1
lines changed

3 files changed

+234
-1
lines changed

tests/stm32/Cargo.toml

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0"
66

77
[features]
88
stm32f103c8 = ["embassy-stm32/stm32f103c8"] # Blue Pill
9-
stm32f429zi = ["embassy-stm32/stm32f429zi"] # Nucleo
9+
stm32f429zi = ["embassy-stm32/stm32f429zi", "sdmmc"] # Nucleo
1010
stm32g071rb = ["embassy-stm32/stm32g071rb"] # Nucleo
1111
stm32c031c6 = ["embassy-stm32/stm32c031c6"] # Nucleo
1212
stm32g491re = ["embassy-stm32/stm32g491re"] # Nucleo
@@ -15,6 +15,8 @@ stm32wb55rg = ["embassy-stm32/stm32wb55rg"] # Nucleo
1515
stm32h563zi = ["embassy-stm32/stm32h563zi"] # Nucleo
1616
stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board
1717

18+
sdmmc = []
19+
1820
[dependencies]
1921
embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
2022
embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
@@ -31,6 +33,45 @@ embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.10" }
3133
embedded-hal-async = { version = "=0.2.0-alpha.1" }
3234
panic-probe = { version = "0.3.0", features = ["print-defmt"] }
3335

36+
# BEGIN TESTS
37+
# Generated by gen_test.py. DO NOT EDIT.
38+
[[bin]]
39+
name = "gpio"
40+
path = "src/bin/gpio.rs"
41+
required-features = []
42+
43+
[[bin]]
44+
name = "sdmmc"
45+
path = "src/bin/sdmmc.rs"
46+
required-features = [ "sdmmc",]
47+
48+
[[bin]]
49+
name = "spi"
50+
path = "src/bin/spi.rs"
51+
required-features = []
52+
53+
[[bin]]
54+
name = "spi_dma"
55+
path = "src/bin/spi_dma.rs"
56+
required-features = []
57+
58+
[[bin]]
59+
name = "timer"
60+
path = "src/bin/timer.rs"
61+
required-features = []
62+
63+
[[bin]]
64+
name = "usart"
65+
path = "src/bin/usart.rs"
66+
required-features = []
67+
68+
[[bin]]
69+
name = "usart_dma"
70+
path = "src/bin/usart_dma.rs"
71+
required-features = []
72+
73+
# END TESTS
74+
3475
[profile.dev]
3576
debug = 2
3677
debug-assertions = true

tests/stm32/gen_test.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import os
2+
import toml
3+
from glob import glob
4+
5+
abspath = os.path.abspath(__file__)
6+
dname = os.path.dirname(abspath)
7+
os.chdir(dname)
8+
9+
# ======= load test list
10+
tests = {}
11+
for f in sorted(glob('./src/bin/*.rs')):
12+
name = os.path.splitext(os.path.basename(f))[0]
13+
features = []
14+
with open(f, 'r') as f:
15+
for line in f:
16+
if line.startswith('// required-features:'):
17+
features = line.split(':', 2)[1].strip().split(',')
18+
19+
tests[name] = features
20+
21+
# ========= Update Cargo.toml
22+
23+
things = {
24+
'bin': [
25+
{
26+
'name': f'{name}',
27+
'path': f'src/bin/{name}.rs',
28+
'required-features': features,
29+
}
30+
for name, features in tests.items()
31+
]
32+
}
33+
34+
SEPARATOR_START = '# BEGIN TESTS\n'
35+
SEPARATOR_END = '# END TESTS\n'
36+
HELP = '# Generated by gen_test.py. DO NOT EDIT.\n'
37+
with open('Cargo.toml', 'r') as f:
38+
data = f.read()
39+
before, data = data.split(SEPARATOR_START, maxsplit=1)
40+
_, after = data.split(SEPARATOR_END, maxsplit=1)
41+
data = before + SEPARATOR_START + HELP + \
42+
toml.dumps(things) + SEPARATOR_END + after
43+
with open('Cargo.toml', 'w') as f:
44+
f.write(data)

tests/stm32/src/bin/sdmmc.rs

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
// required-features: sdmmc
2+
#![no_std]
3+
#![no_main]
4+
#![feature(type_alias_impl_trait)]
5+
6+
use defmt::{assert_eq, *};
7+
use embassy_executor::Spawner;
8+
use embassy_stm32::sdmmc::{DataBlock, Sdmmc};
9+
use embassy_stm32::time::mhz;
10+
use embassy_stm32::{interrupt, Config};
11+
use {defmt_rtt as _, panic_probe as _};
12+
13+
#[embassy_executor::main]
14+
async fn main(_spawner: Spawner) {
15+
info!("Hello World!");
16+
17+
let mut config = Config::default();
18+
config.rcc.sys_ck = Some(mhz(48));
19+
config.rcc.pll48 = true;
20+
let p = embassy_stm32::init(config);
21+
22+
#[cfg(feature = "stm32f429zi")]
23+
let (mut sdmmc, mut irq, mut dma, mut clk, mut cmd, mut d0, mut d1, mut d2, mut d3) = (
24+
p.SDIO,
25+
interrupt::take!(SDIO),
26+
p.DMA2_CH3,
27+
p.PC12,
28+
p.PD2,
29+
p.PC8,
30+
p.PC9,
31+
p.PC10,
32+
p.PC11,
33+
);
34+
35+
// Arbitrary block index
36+
let block_idx = 16;
37+
38+
let mut pattern1 = DataBlock([0u8; 512]);
39+
let mut pattern2 = DataBlock([0u8; 512]);
40+
for i in 0..512 {
41+
pattern1[i] = i as u8;
42+
pattern2[i] = !i as u8;
43+
}
44+
45+
let mut block = DataBlock([0u8; 512]);
46+
47+
// ======== Try 4bit. ==============
48+
info!("initializing in 4-bit mode...");
49+
let mut s = Sdmmc::new_4bit(
50+
&mut sdmmc,
51+
&mut irq,
52+
&mut dma,
53+
&mut clk,
54+
&mut cmd,
55+
&mut d0,
56+
&mut d1,
57+
&mut d2,
58+
&mut d3,
59+
Default::default(),
60+
);
61+
62+
let mut err = None;
63+
loop {
64+
match s.init_card(mhz(24)).await {
65+
Ok(_) => break,
66+
Err(e) => {
67+
if err != Some(e) {
68+
info!("waiting for card: {:?}", e);
69+
err = Some(e);
70+
}
71+
}
72+
}
73+
}
74+
75+
let card = unwrap!(s.card());
76+
77+
info!("Card: {:#?}", Debug2Format(card));
78+
info!("Clock: {}", s.clock());
79+
80+
info!("writing pattern1...");
81+
s.write_block(block_idx, &pattern1).await.unwrap();
82+
83+
info!("reading...");
84+
s.read_block(block_idx, &mut block).await.unwrap();
85+
assert_eq!(block, pattern1);
86+
87+
info!("writing pattern2...");
88+
s.write_block(block_idx, &pattern2).await.unwrap();
89+
90+
info!("reading...");
91+
s.read_block(block_idx, &mut block).await.unwrap();
92+
assert_eq!(block, pattern2);
93+
94+
drop(s);
95+
96+
// ======== Try 1bit. ==============
97+
info!("initializing in 1-bit mode...");
98+
let mut s = Sdmmc::new_1bit(
99+
&mut sdmmc,
100+
&mut irq,
101+
&mut dma,
102+
&mut clk,
103+
&mut cmd,
104+
&mut d0,
105+
Default::default(),
106+
);
107+
108+
let mut err = None;
109+
loop {
110+
match s.init_card(mhz(24)).await {
111+
Ok(_) => break,
112+
Err(e) => {
113+
if err != Some(e) {
114+
info!("waiting for card: {:?}", e);
115+
err = Some(e);
116+
}
117+
}
118+
}
119+
}
120+
121+
let card = unwrap!(s.card());
122+
123+
info!("Card: {:#?}", Debug2Format(card));
124+
info!("Clock: {}", s.clock());
125+
126+
info!("reading pattern2 written in 4bit mode...");
127+
s.read_block(block_idx, &mut block).await.unwrap();
128+
assert_eq!(block, pattern2);
129+
130+
info!("writing pattern1...");
131+
s.write_block(block_idx, &pattern1).await.unwrap();
132+
133+
info!("reading...");
134+
s.read_block(block_idx, &mut block).await.unwrap();
135+
assert_eq!(block, pattern1);
136+
137+
info!("writing pattern2...");
138+
s.write_block(block_idx, &pattern2).await.unwrap();
139+
140+
info!("reading...");
141+
s.read_block(block_idx, &mut block).await.unwrap();
142+
assert_eq!(block, pattern2);
143+
144+
drop(s);
145+
146+
info!("Test OK");
147+
cortex_m::asm::bkpt();
148+
}

0 commit comments

Comments
 (0)