forked from stm32-rs/stm32h7xx-hal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
octospi_hyperram.rs
172 lines (151 loc) · 4.32 KB
/
octospi_hyperram.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
//! Example using a OCTOSPI HyperRAM in memory-mapped mode
//!
//! Tested on a STM32H735G-DK with a Cypress S70KL1281DABHI023
#![deny(warnings)]
#![no_main]
#![no_std]
use core::mem;
use core::slice;
#[macro_use]
mod utilities;
use cortex_m_rt::entry;
use stm32h7xx_hal::rcc::rec::{OctospiClkSel, OctospiClkSelGetter};
use stm32h7xx_hal::{gpio::Speed::High, pac, prelude::*, xspi::HyperbusConfig};
use log::info;
#[entry]
fn main() -> ! {
utilities::logger::init();
let dp = pac::Peripherals::take().unwrap();
// Constrain and Freeze power
let pwr = dp.PWR.constrain();
let pwrcfg = example_power!(pwr).freeze();
// Constrain and Freeze clock
let rcc = dp.RCC.constrain();
let ccdr = rcc.sys_ck(320.MHz()).freeze(pwrcfg, &dp.SYSCFG);
// Octospi from HCLK at 160MHz
assert_eq!(ccdr.clocks.hclk().raw(), 160_000_000);
assert_eq!(
ccdr.peripheral.OCTOSPI1.get_kernel_clk_mux(),
OctospiClkSel::RccHclk3
);
// Acquire the GPIO peripherals. This also enables the clock for
// the GPIOs in the RCC register.
let gpiog = dp.GPIOG.split(ccdr.peripheral.GPIOG);
let gpiob = dp.GPIOB.split(ccdr.peripheral.GPIOB);
let gpiof = dp.GPIOF.split(ccdr.peripheral.GPIOF);
let _tracweswo = gpiob.pb3.into_alternate::<0>();
let _ncs = gpiog
.pg12
.into_alternate::<3>()
.speed(High)
.internal_pull_up(true);
let _dqs = gpiof
.pf12
.into_alternate::<9>()
.speed(High)
.internal_pull_up(true);
let _clk = gpiof
.pf4
.into_alternate::<9>()
.speed(High)
.internal_pull_up(true);
let _io0 = gpiof
.pf0
.into_alternate::<9>()
.speed(High)
.internal_pull_up(true);
let _io1 = gpiof
.pf1
.into_alternate::<9>()
.speed(High)
.internal_pull_up(true);
let _io2 = gpiof
.pf2
.into_alternate::<9>()
.speed(High)
.internal_pull_up(true);
let _io3 = gpiof
.pf3
.into_alternate::<9>()
.speed(High)
.internal_pull_up(true);
let _io4 = gpiog
.pg0
.into_alternate::<9>()
.speed(High)
.internal_pull_up(true);
let _io5 = gpiog
.pg1
.into_alternate::<9>()
.speed(High)
.internal_pull_up(true);
let _io6 = gpiog
.pg10
.into_alternate::<3>()
.speed(High)
.internal_pull_up(true);
let _io7 = gpiog
.pg11
.into_alternate::<9>()
.speed(High)
.internal_pull_up(true);
info!("");
info!("stm32h7xx-hal example - OCTOSPI HyperRAM");
info!("");
// Initialise a HyperRAM on the OCTOSPI2 peripheral
let ram_slice = unsafe {
let hyperram_size = 16 * 1024 * 1024; // 16 MByte
let config = HyperbusConfig::new(80.MHz())
.device_size_bytes(24) // 16 Mbyte
.refresh_interval(4.micros())
.read_write_recovery(4) // 50ns
.access_initial_latency(6);
let hyperram = dp.OCTOSPI2.octospi_hyperbus_unchecked(
config,
&ccdr.clocks,
ccdr.peripheral.OCTOSPI2,
);
info!("Created HyperRAM..");
info!("{}", hyperram);
info!("");
// Initialise and convert raw pointer to slice
let ram_ptr: *mut u32 = hyperram.init();
slice::from_raw_parts_mut(
ram_ptr,
hyperram_size / mem::size_of::<u32>(),
)
};
info!("Writing checkerboard pattern...");
for x in ram_slice.iter_mut() {
*x = 0xAA55AA55;
}
info!("Reading checkerboard pattern...");
for (i, x) in ram_slice.iter().enumerate() {
assert_eq!(
*x,
0xAA55AA55,
"Mismatch at address 0x{:x} (0x{:x} != 0xaa55aa55)",
i * 4,
*x
);
}
info!("Writing reverse checkerboard pattern...");
for x in ram_slice.iter_mut() {
*x = 0x55AA55AA;
}
info!("Reading reverse checkerboard pattern...");
for (i, x) in ram_slice.iter().enumerate() {
assert_eq!(
*x,
0x55AA55AA,
"Mismatch at address 0x{:x} (0x{:x} != 0x55aa55aa)",
i * 4,
*x
);
}
info!("Success!");
info!("");
loop {
cortex_m::asm::nop();
}
}