aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-10-21 00:31:36 +0000
committerGitHub <[email protected]>2024-10-21 00:31:36 +0000
commitd8ae5861db3ae5b7e96226d4a525d0d8e20c1816 (patch)
tree8e2f5f30913369f92fb1a9ca7bd269017d80ddc7
parent4a1d18939308b57a2562b3c00ecd3b3d4416b6cf (diff)
parent1d395fc2b6e5d3d870afb90593de9f03d47b0efa (diff)
Merge pull request #3305 from Luctins/stm32h5-flash-driver
Add STM32H5 flash driver
-rw-r--r--embassy-stm32/src/flash/h5.rs177
-rw-r--r--embassy-stm32/src/flash/mod.rs5
2 files changed, 180 insertions, 2 deletions
diff --git a/embassy-stm32/src/flash/h5.rs b/embassy-stm32/src/flash/h5.rs
new file mode 100644
index 000000000..9e131ca2b
--- /dev/null
+++ b/embassy-stm32/src/flash/h5.rs
@@ -0,0 +1,177 @@
1use core::ptr::write_volatile;
2use core::sync::atomic::{fence, Ordering};
3
4use super::{FlashRegion, FlashSector, FLASH_REGIONS, WRITE_SIZE};
5use crate::flash::Error;
6use crate::pac;
7
8pub(crate) const fn is_default_layout() -> bool {
9 true
10}
11
12// const fn is_dual_bank() -> bool {
13// FLASH_REGIONS.len() >= 2
14// }
15
16pub(crate) fn get_flash_regions() -> &'static [&'static FlashRegion] {
17 &FLASH_REGIONS
18}
19
20pub(crate) unsafe fn lock() {
21 if !pac::FLASH.nscr().read().lock() {
22 pac::FLASH.nscr().modify(|r| {
23 r.set_lock(true);
24 });
25 }
26}
27
28pub(crate) unsafe fn unlock() {
29 // TODO: check locked first
30 while pac::FLASH.nssr().read().bsy() {
31 #[cfg(feature = "defmt")]
32 defmt::trace!("busy")
33 }
34
35 // only unlock if locked to begin with
36 if pac::FLASH.nscr().read().lock() {
37 pac::FLASH.nskeyr().write_value(0x4567_0123);
38 pac::FLASH.nskeyr().write_value(0xCDEF_89AB);
39 }
40}
41
42pub(crate) unsafe fn enable_blocking_write() {
43 assert_eq!(0, WRITE_SIZE % 4);
44}
45
46pub(crate) unsafe fn disable_blocking_write() {}
47
48pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> {
49 // // We cannot have the write setup sequence in begin_write as it depends on the address
50 // let bank = if start_address < BANK1_REGION.end() {
51 // pac::FLASH.bank(0)
52 // } else {
53 // pac::FLASH.bank(1)
54 // };
55
56 cortex_m::asm::isb();
57 cortex_m::asm::dsb();
58 fence(Ordering::SeqCst);
59
60 clear_all_err();
61
62 pac::FLASH.nscr().write(|w| {
63 w.set_pg(true);
64 // w.set_psize(2); // 32 bits at once
65 });
66
67 let mut res = None;
68 let mut address = start_address;
69 // TODO: see write size
70 for val in buf.chunks(4) {
71 write_volatile(address as *mut u32, u32::from_le_bytes(unwrap!(val.try_into())));
72 address += val.len() as u32;
73
74 res = Some(blocking_wait_ready().map_err(|e| {
75 error!("write err");
76 e
77 }));
78 pac::FLASH.nssr().modify(|w| {
79 if w.eop() {
80 w.set_eop(true);
81 }
82 });
83 if unwrap!(res).is_err() {
84 break;
85 }
86 }
87
88 cortex_m::asm::isb();
89 cortex_m::asm::dsb();
90 fence(Ordering::SeqCst);
91
92 pac::FLASH.nscr().write(|w| w.set_pg(false));
93
94 unwrap!(res)
95}
96
97pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), Error> {
98 // pac::FLASH.wrp2r_cur().read().wrpsg()
99 // TODO: write protection check
100 if pac::FLASH.nscr().read().lock() == true {
101 error!("flash locked");
102 }
103
104 loop {
105 let sr = pac::FLASH.nssr().read();
106 if !sr.bsy() && !sr.dbne() {
107 break;
108 }
109 }
110 clear_all_err();
111
112 pac::FLASH.nscr().modify(|r| {
113 // TODO: later check bank swap
114 r.set_bksel(match sector.bank {
115 crate::flash::FlashBank::Bank1 => stm32_metapac::flash::vals::NscrBksel::B_0X0,
116 crate::flash::FlashBank::Bank2 => stm32_metapac::flash::vals::NscrBksel::B_0X1,
117 });
118 r.set_snb(sector.index_in_bank);
119 r.set_ser(true);
120 });
121
122 pac::FLASH.nscr().modify(|r| {
123 r.set_strt(true);
124 });
125
126 cortex_m::asm::isb();
127 cortex_m::asm::dsb();
128 fence(Ordering::SeqCst);
129
130 let ret: Result<(), Error> = blocking_wait_ready().map_err(|e| {
131 error!("erase err");
132 e
133 });
134
135 pac::FLASH.nscr().modify(|w| w.set_ser(false));
136 clear_all_err();
137 ret
138}
139
140pub(crate) unsafe fn clear_all_err() {
141 pac::FLASH.nssr().modify(|_| {})
142}
143
144unsafe fn blocking_wait_ready() -> Result<(), Error> {
145 loop {
146 let sr = pac::FLASH.nssr().read();
147
148 if !sr.bsy() {
149 if sr.optchangeerr() {
150 error!("optchangeerr");
151 return Err(Error::Prog);
152 }
153 if sr.obkwerr() {
154 error!("obkwerr");
155 return Err(Error::Seq);
156 }
157 if sr.obkerr() {
158 error!("obkerr");
159 return Err(Error::Seq);
160 }
161 if sr.incerr() {
162 error!("incerr");
163 return Err(Error::Unaligned);
164 }
165 if sr.strberr() {
166 error!("strberr");
167 return Err(Error::Parallelism);
168 }
169 if sr.wrperr() {
170 error!("protected");
171 return Err(Error::Protected);
172 }
173
174 return Ok(());
175 }
176 }
177}
diff --git a/embassy-stm32/src/flash/mod.rs b/embassy-stm32/src/flash/mod.rs
index d64a1c28a..88fe6a291 100644
--- a/embassy-stm32/src/flash/mod.rs
+++ b/embassy-stm32/src/flash/mod.rs
@@ -101,13 +101,14 @@ pub enum FlashBank {
101#[cfg_attr(flash_h7, path = "h7.rs")] 101#[cfg_attr(flash_h7, path = "h7.rs")]
102#[cfg_attr(flash_h7ab, path = "h7.rs")] 102#[cfg_attr(flash_h7ab, path = "h7.rs")]
103#[cfg_attr(flash_u5, path = "u5.rs")] 103#[cfg_attr(flash_u5, path = "u5.rs")]
104#[cfg_attr(flash_h5, path = "h5.rs")]
104#[cfg_attr(flash_h50, path = "h50.rs")] 105#[cfg_attr(flash_h50, path = "h50.rs")]
105#[cfg_attr(flash_u0, path = "u0.rs")] 106#[cfg_attr(flash_u0, path = "u0.rs")]
106#[cfg_attr( 107#[cfg_attr(
107 not(any( 108 not(any(
108 flash_l0, flash_l1, flash_l4, flash_l5, flash_wl, flash_wb, flash_f0, flash_f1, flash_f2, flash_f3, flash_f4, 109 flash_l0, flash_l1, flash_l4, flash_l5, flash_wl, flash_wb, flash_f0, flash_f1, flash_f2, flash_f3, flash_f4,
109 flash_f7, flash_g0, flash_g0, flash_g4c2, flash_g4c3, flash_g4c4, flash_h7, flash_h7ab, flash_u5, flash_h50, 110 flash_f7, flash_g0, flash_g4c2, flash_g4c3, flash_g4c4, flash_h7, flash_h7ab, flash_u5, flash_h50, flash_u0,
110 flash_u0 111 flash_h5,
111 )), 112 )),
112 path = "other.rs" 113 path = "other.rs"
113)] 114)]