aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorMatous Hybl <[email protected]>2022-02-08 14:32:18 +0100
committerMatous Hybl <[email protected]>2022-02-08 17:30:20 +0100
commitd37d714314093747c9042faefcc3a22e2bfee59d (patch)
tree16f9b8ce5d8e58f7b6cf32f8071f394795f8300b /examples
parentfee1de109dc5a81ee4e2a74403faec0923e0369e (diff)
stm32: Add support for FMC
Diffstat (limited to 'examples')
-rw-r--r--examples/stm32h7/Cargo.toml3
-rw-r--r--examples/stm32h7/src/bin/fmc.rs204
-rw-r--r--examples/stm32h7/src/example_common.rs1
3 files changed, 207 insertions, 1 deletions
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml
index 463dd83d5..59d99bbcb 100644
--- a/examples/stm32h7/Cargo.toml
+++ b/examples/stm32h7/Cargo.toml
@@ -9,7 +9,7 @@ resolver = "2"
9 9
10[dependencies] 10[dependencies]
11embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } 11embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] }
12embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743zi", "net", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] } 12embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32h743bi", "net", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] }
13embassy-net = { path = "../../embassy-net", default-features = false, features = ["defmt", "tcp", "medium-ethernet", "pool-16"] } 13embassy-net = { path = "../../embassy-net", default-features = false, features = ["defmt", "tcp", "medium-ethernet", "pool-16"] }
14embassy-hal-common = { path = "../../embassy-hal-common", default-features = false, features = ["defmt"] } 14embassy-hal-common = { path = "../../embassy-hal-common", default-features = false, features = ["defmt"] }
15 15
@@ -26,6 +26,7 @@ heapless = { version = "0.7.5", default-features = false }
26rand_core = "0.6.3" 26rand_core = "0.6.3"
27critical-section = "0.2.5" 27critical-section = "0.2.5"
28micromath = "2.0.0" 28micromath = "2.0.0"
29stm32-fmc = "0.2.4"
29 30
30[dependencies.smoltcp] 31[dependencies.smoltcp]
31version = "0.8.0" 32version = "0.8.0"
diff --git a/examples/stm32h7/src/bin/fmc.rs b/examples/stm32h7/src/bin/fmc.rs
new file mode 100644
index 000000000..b9ac1318e
--- /dev/null
+++ b/examples/stm32h7/src/bin/fmc.rs
@@ -0,0 +1,204 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5#[path = "../example_common.rs"]
6mod example_common;
7use embassy::executor::Spawner;
8use embassy::time::{Delay, Duration, Timer};
9use embassy_stm32::fmc::Fmc;
10use embassy_stm32::Peripherals;
11use example_common::*;
12
13#[embassy::main(config = "config()")]
14async fn main(_spawner: Spawner, p: Peripherals) {
15 info!("Hello World!");
16
17 let mut core_peri = cortex_m::Peripherals::take().unwrap();
18
19 // taken from stm32h7xx-hal
20 core_peri.SCB.enable_icache();
21 // See Errata Sheet 2.2.1
22 // core_peri.SCB.enable_dcache(&mut core_peri.CPUID);
23 core_peri.DWT.enable_cycle_counter();
24 // ----------------------------------------------------------
25 // Configure MPU for external SDRAM
26 // MPU config for SDRAM write-through
27 let sdram_size = 32 * 1024 * 1024;
28
29 {
30 let mpu = core_peri.MPU;
31 let scb = &mut core_peri.SCB;
32 let size = sdram_size;
33 // Refer to ARM®v7-M Architecture Reference Manual ARM DDI 0403
34 // Version E.b Section B3.5
35 const MEMFAULTENA: u32 = 1 << 16;
36
37 unsafe {
38 /* Make sure outstanding transfers are done */
39 cortex_m::asm::dmb();
40
41 scb.shcsr.modify(|r| r & !MEMFAULTENA);
42
43 /* Disable the MPU and clear the control register*/
44 mpu.ctrl.write(0);
45 }
46
47 const REGION_NUMBER0: u32 = 0x00;
48 const REGION_BASE_ADDRESS: u32 = 0xD000_0000;
49
50 const REGION_FULL_ACCESS: u32 = 0x03;
51 const REGION_CACHEABLE: u32 = 0x01;
52 const REGION_WRITE_BACK: u32 = 0x01;
53 const REGION_ENABLE: u32 = 0x01;
54
55 crate::assert_eq!(
56 size & (size - 1),
57 0,
58 "SDRAM memory region size must be a power of 2"
59 );
60 crate::assert_eq!(
61 size & 0x1F,
62 0,
63 "SDRAM memory region size must be 32 bytes or more"
64 );
65 fn log2minus1(sz: u32) -> u32 {
66 for i in 5..=31 {
67 if sz == (1 << i) {
68 return i - 1;
69 }
70 }
71 crate::panic!("Unknown SDRAM memory region size!");
72 }
73
74 //info!("SDRAM Memory Size 0x{:x}", log2minus1(size as u32));
75
76 // Configure region 0
77 //
78 // Cacheable, outer and inner write-back, no write allocate. So
79 // reads are cached, but writes always write all the way to SDRAM
80 unsafe {
81 mpu.rnr.write(REGION_NUMBER0);
82 mpu.rbar.write(REGION_BASE_ADDRESS);
83 mpu.rasr.write(
84 (REGION_FULL_ACCESS << 24)
85 | (REGION_CACHEABLE << 17)
86 | (REGION_WRITE_BACK << 16)
87 | (log2minus1(size as u32) << 1)
88 | REGION_ENABLE,
89 );
90 }
91
92 const MPU_ENABLE: u32 = 0x01;
93 const MPU_DEFAULT_MMAP_FOR_PRIVILEGED: u32 = 0x04;
94
95 // Enable
96 unsafe {
97 mpu.ctrl
98 .modify(|r| r | MPU_DEFAULT_MMAP_FOR_PRIVILEGED | MPU_ENABLE);
99
100 scb.shcsr.modify(|r| r | MEMFAULTENA);
101
102 // Ensure MPU settings take effect
103 cortex_m::asm::dsb();
104 cortex_m::asm::isb();
105 }
106 }
107
108 let mut sdram = Fmc::sdram_a12bits_d32bits_4banks_bank2(
109 p.FMC,
110 // A0-A11
111 p.PF0,
112 p.PF1,
113 p.PF2,
114 p.PF3,
115 p.PF4,
116 p.PF5,
117 p.PF12,
118 p.PF13,
119 p.PF14,
120 p.PF15,
121 p.PG0,
122 p.PG1,
123 // BA0-BA1
124 p.PG4,
125 p.PG5,
126 // D0-D31
127 p.PD14,
128 p.PD15,
129 p.PD0,
130 p.PD1,
131 p.PE7,
132 p.PE8,
133 p.PE9,
134 p.PE10,
135 p.PE11,
136 p.PE12,
137 p.PE13,
138 p.PE14,
139 p.PE15,
140 p.PD8,
141 p.PD9,
142 p.PD10,
143 p.PH8,
144 p.PH9,
145 p.PH10,
146 p.PH11,
147 p.PH12,
148 p.PH13,
149 p.PH14,
150 p.PH15,
151 p.PI0,
152 p.PI1,
153 p.PI2,
154 p.PI3,
155 p.PI6,
156 p.PI7,
157 p.PI9,
158 p.PI10,
159 // NBL0 - NBL3
160 p.PE0,
161 p.PE1,
162 p.PI4,
163 p.PI5,
164 p.PH7, // SDCKE1
165 p.PG8, // SDCLK
166 p.PG15, // SDNCAS
167 p.PH6, // SDNE1 (!CS)
168 p.PF11, // SDRAS
169 p.PC0, // SDNWE, change to p.PH5 for EVAL boards
170 stm32_fmc::devices::is42s32800g_6::Is42s32800g {},
171 );
172
173 let mut delay = Delay;
174
175 let ram_slice = unsafe {
176 // Initialise controller and SDRAM
177 let ram_ptr: *mut u32 = sdram.init(&mut delay) as *mut _;
178
179 // Convert raw pointer to slice
180 core::slice::from_raw_parts_mut(ram_ptr, sdram_size / core::mem::size_of::<u32>())
181 };
182
183 // // ----------------------------------------------------------
184 // // Use memory in SDRAM
185 info!("RAM contents before writing: {:x}", ram_slice[..10]);
186
187 ram_slice[0] = 1;
188 ram_slice[1] = 2;
189 ram_slice[2] = 3;
190 ram_slice[3] = 4;
191
192 info!("RAM contents after writing: {:x}", ram_slice[..10]);
193
194 crate::assert_eq!(ram_slice[0], 1);
195 crate::assert_eq!(ram_slice[1], 2);
196 crate::assert_eq!(ram_slice[2], 3);
197 crate::assert_eq!(ram_slice[3], 4);
198
199 info!("Assertions succeeded.");
200
201 loop {
202 Timer::after(Duration::from_millis(1000)).await;
203 }
204}
diff --git a/examples/stm32h7/src/example_common.rs b/examples/stm32h7/src/example_common.rs
index 524bee6d9..b8acc2790 100644
--- a/examples/stm32h7/src/example_common.rs
+++ b/examples/stm32h7/src/example_common.rs
@@ -22,6 +22,7 @@ defmt::timestamp! {"{=u64}", {
22pub fn config() -> Config { 22pub fn config() -> Config {
23 let mut config = Config::default(); 23 let mut config = Config::default();
24 config.rcc.sys_ck = Some(400.mhz().into()); 24 config.rcc.sys_ck = Some(400.mhz().into());
25 config.rcc.hclk = Some(200.mhz().into());
25 config.rcc.pll1.q_ck = Some(100.mhz().into()); 26 config.rcc.pll1.q_ck = Some(100.mhz().into());
26 config 27 config
27} 28}