Skip to content

Commit 3e9f168

Browse files
authored
Merge pull request #107 from bbrown1867/add-minimal-qspi-driver
Add QSPI driver and example
2 parents f6ccb4d + 2bc77e4 commit 3e9f168

File tree

6 files changed

+776
-0
lines changed

6 files changed

+776
-0
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,7 @@ required-features = ["stm32f723", "rt", "synopsys-usb-otg"]
129129

130130
[[example]]
131131
name = "rng"
132+
133+
[[example]]
134+
name = "stm32f7disco-qspi-flash"
135+
required-features = ["stm32f746", "rt"]
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
//! Example code showing how to use the MT25QL128ABA on the STM32F746G Discovery Board.
2+
//! The intended behavior of the example is to write a known pattern to flash memory and
3+
//! read it back using both polling and DMA indirect modes of the QSPI HAL driver.
4+
//! The example will panic on failure and print messages over the debugger on success.
5+
//! See `mt25q.rs` for more details on the QSPI HAL driver.
6+
7+
#![no_main]
8+
#![no_std]
9+
10+
extern crate panic_semihosting;
11+
12+
use cortex_m_rt::entry;
13+
use cortex_m_semihosting::hprintln;
14+
use stm32f7xx_hal::{
15+
dma::{Handle, Stream7, DMA},
16+
pac::{self, DMA2},
17+
prelude::*,
18+
rcc::{HSEClock, HSEClockMode, RccExt},
19+
state,
20+
};
21+
22+
mod mt25q;
23+
24+
#[entry]
25+
fn main() -> ! {
26+
let pac_periph = pac::Peripherals::take().unwrap();
27+
let mut rcc = pac_periph.RCC;
28+
29+
// Initialize flash driver, which will initialize QSPI driver
30+
let mut mt25q = mt25q::Mt25q::new(
31+
&mut rcc,
32+
pac_periph.GPIOB,
33+
pac_periph.GPIOD,
34+
pac_periph.GPIOE,
35+
pac_periph.QUADSPI,
36+
);
37+
38+
// Init clocks
39+
let hse_cfg = HSEClock::new(25.mhz(), HSEClockMode::Oscillator);
40+
let mut rcc = rcc.constrain();
41+
42+
// Setup DMA
43+
let dma = DMA::new(pac_periph.DMA2);
44+
let stream = dma.streams.stream7;
45+
let dma = dma.handle.enable(&mut rcc.ahb1);
46+
47+
// Ramp up clocks to 216 MHz
48+
rcc.cfgr.hse(hse_cfg).sysclk(216.mhz()).freeze();
49+
50+
// Check that we can communicate with the flash device
51+
mt25q.check_id();
52+
53+
memory_example_polling(&mut mt25q);
54+
memory_example_dma(&mut mt25q, &dma, stream);
55+
56+
loop {}
57+
}
58+
59+
fn memory_example_polling(mt25q: &mut mt25q::Mt25q) {
60+
// Create a set of buffers for a memory at address `ADDR` of size `LEN` bytes
61+
const ADDR: u32 = 0x7003;
62+
const LEN: usize = 1035;
63+
let mut read_buffer: [u8; LEN] = [0; LEN];
64+
let mut write_buffer: [u8; LEN] = [0; LEN];
65+
for i in 0..LEN {
66+
write_buffer[i] = i as u8;
67+
}
68+
69+
// Test erase + read
70+
let (num_erase, addr_erase) = mt25q.erase(ADDR, LEN);
71+
assert!(LEN <= num_erase as usize);
72+
assert!(addr_erase <= ADDR);
73+
74+
mt25q.read(&mut read_buffer, ADDR, LEN);
75+
for i in 0..LEN {
76+
assert!(read_buffer[i] == 0xFF);
77+
}
78+
79+
// Test write + read
80+
mt25q.write(ADDR, &mut write_buffer, LEN);
81+
mt25q.read(&mut read_buffer, ADDR, LEN);
82+
for i in 0..LEN {
83+
if write_buffer[i] != read_buffer[i] {
84+
panic!(
85+
"Error: Mismatch at address {:X}. Expected {:X} but read {:X}",
86+
ADDR + i as u32,
87+
write_buffer[i],
88+
read_buffer[i]
89+
);
90+
}
91+
}
92+
93+
hprintln!("Flash device memory test successful!").unwrap();
94+
}
95+
96+
fn memory_example_dma(
97+
mt25q: &mut mt25q::Mt25q,
98+
dma: &Handle<DMA2, state::Enabled>,
99+
stream: Stream7<DMA2>,
100+
) {
101+
// Create a set of buffers for a memory at address `ADDR` of size `LEN` bytes
102+
const ADDR: u32 = 0x7000;
103+
const LEN: usize = 4096;
104+
let mut read_buffer: [u8; LEN] = [0; LEN];
105+
let mut write_buffer: [u8; LEN] = [0; LEN];
106+
for i in 0..LEN {
107+
write_buffer[i] = i as u8;
108+
}
109+
110+
// Test erase + read
111+
let (num_erase, addr_erase) = mt25q.erase(ADDR, LEN);
112+
assert!(LEN <= num_erase as usize);
113+
assert!(addr_erase <= ADDR);
114+
115+
let stream = mt25q.read_dma(&mut read_buffer, ADDR, LEN, dma, stream);
116+
for i in 0..LEN {
117+
assert!(read_buffer[i] == 0xFF);
118+
}
119+
120+
// Test write + read
121+
let stream = mt25q.write_dma(ADDR, &mut write_buffer, LEN, dma, stream);
122+
mt25q.read_dma(&mut read_buffer, ADDR, LEN, dma, stream);
123+
for i in 0..LEN {
124+
if write_buffer[i] != read_buffer[i] {
125+
panic!(
126+
"Error: Mismatch at address {:X}. Expected {:X} but read {:X}",
127+
ADDR + i as u32,
128+
write_buffer[i],
129+
read_buffer[i]
130+
);
131+
}
132+
}
133+
134+
hprintln!("Flash device memory DMA test successful!").unwrap();
135+
}

0 commit comments

Comments
 (0)