aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/flash
diff options
context:
space:
mode:
authorMaxime Vincent <[email protected]>2024-09-02 12:05:33 +0200
committerMaxime Vincent <[email protected]>2024-09-02 12:25:42 +0200
commit82f274ea097c4aef35cb452d94654f94ab549895 (patch)
treee9594e01d4b85fd2525593a60c972b9cebf8bcbc /embassy-stm32/src/flash
parentf0a86070512ad739641cee7d9fa39d63f5c8a9f6 (diff)
stm32: add f2 flash support (blocking)
Diffstat (limited to 'embassy-stm32/src/flash')
-rw-r--r--embassy-stm32/src/flash/f2.rs142
-rw-r--r--embassy-stm32/src/flash/mod.rs5
2 files changed, 145 insertions, 2 deletions
diff --git a/embassy-stm32/src/flash/f2.rs b/embassy-stm32/src/flash/f2.rs
new file mode 100644
index 000000000..cdab1fd2d
--- /dev/null
+++ b/embassy-stm32/src/flash/f2.rs
@@ -0,0 +1,142 @@
1use core::ptr::write_volatile;
2use core::sync::atomic::{fence, AtomicBool, Ordering};
3
4use pac::flash::regs::Sr;
5
6use super::{FlashBank, FlashRegion, FlashSector, FLASH_REGIONS, WRITE_SIZE};
7use crate::flash::Error;
8use crate::pac;
9
10static DATA_CACHE_WAS_ENABLED: AtomicBool = AtomicBool::new(false);
11
12impl FlashSector {
13 const fn snb(&self) -> u8 {
14 ((self.bank as u8) << 4) + self.index_in_bank
15 }
16}
17
18pub(crate) const fn is_default_layout() -> bool {
19 true
20}
21
22pub(crate) const fn get_flash_regions() -> &'static [&'static FlashRegion] {
23 &FLASH_REGIONS
24}
25
26pub(crate) unsafe fn lock() {
27 pac::FLASH.cr().modify(|w| w.set_lock(true));
28}
29
30pub(crate) unsafe fn unlock() {
31 if pac::FLASH.cr().read().lock() {
32 pac::FLASH.keyr().write_value(0x4567_0123);
33 pac::FLASH.keyr().write_value(0xCDEF_89AB);
34 }
35}
36
37pub(crate) unsafe fn enable_blocking_write() {
38 assert_eq!(0, WRITE_SIZE % 4);
39 save_data_cache_state();
40
41 pac::FLASH.cr().write(|w| {
42 w.set_pg(true);
43 w.set_psize(pac::flash::vals::Psize::PSIZE32);
44 });
45}
46
47pub(crate) unsafe fn disable_blocking_write() {
48 pac::FLASH.cr().write(|w| w.set_pg(false));
49 restore_data_cache_state();
50}
51
52pub(crate) unsafe fn blocking_write(start_address: u32, buf: &[u8; WRITE_SIZE]) -> Result<(), Error> {
53 write_start(start_address, buf);
54 blocking_wait_ready()
55}
56
57unsafe fn write_start(start_address: u32, buf: &[u8; WRITE_SIZE]) {
58 let mut address = start_address;
59 for val in buf.chunks(4) {
60 write_volatile(address as *mut u32, u32::from_le_bytes(unwrap!(val.try_into())));
61 address += val.len() as u32;
62
63 // prevents parallelism errors
64 fence(Ordering::SeqCst);
65 }
66}
67
68pub(crate) unsafe fn blocking_erase_sector(sector: &FlashSector) -> Result<(), Error> {
69 save_data_cache_state();
70
71 trace!("Blocking erasing sector number {}", sector.snb());
72
73 pac::FLASH.cr().modify(|w| {
74 w.set_ser(true);
75 w.set_snb(sector.snb())
76 });
77
78 pac::FLASH.cr().modify(|w| {
79 w.set_strt(true);
80 });
81
82 let ret: Result<(), Error> = blocking_wait_ready();
83 clear_all_err();
84 restore_data_cache_state();
85 ret
86}
87
88pub(crate) unsafe fn clear_all_err() {
89 // read and write back the same value.
90 // This clears all "write 1 to clear" bits.
91 pac::FLASH.sr().modify(|_| {});
92}
93
94unsafe fn blocking_wait_ready() -> Result<(), Error> {
95 loop {
96 let sr = pac::FLASH.sr().read();
97
98 if !sr.bsy() {
99 return get_result(sr);
100 }
101 }
102}
103
104fn get_result(sr: Sr) -> Result<(), Error> {
105 if sr.pgserr() {
106 Err(Error::Seq)
107 } else if sr.pgperr() {
108 Err(Error::Parallelism)
109 } else if sr.pgaerr() {
110 Err(Error::Unaligned)
111 } else if sr.wrperr() {
112 Err(Error::Protected)
113 } else {
114 Ok(())
115 }
116}
117
118fn save_data_cache_state() {
119 let dual_bank = unwrap!(get_flash_regions().last()).bank == FlashBank::Bank2;
120 if dual_bank {
121 // Disable data cache during write/erase if there are two banks, see errata 2.2.12
122 let dcen = pac::FLASH.acr().read().dcen();
123 DATA_CACHE_WAS_ENABLED.store(dcen, Ordering::Relaxed);
124 if dcen {
125 pac::FLASH.acr().modify(|w| w.set_dcen(false));
126 }
127 }
128}
129
130fn restore_data_cache_state() {
131 let dual_bank = unwrap!(get_flash_regions().last()).bank == FlashBank::Bank2;
132 if dual_bank {
133 // Restore data cache if it was enabled
134 let dcen = DATA_CACHE_WAS_ENABLED.load(Ordering::Relaxed);
135 if dcen {
136 // Reset data cache before we enable it again
137 pac::FLASH.acr().modify(|w| w.set_dcrst(true));
138 pac::FLASH.acr().modify(|w| w.set_dcrst(false));
139 pac::FLASH.acr().modify(|w| w.set_dcen(true))
140 }
141 }
142}
diff --git a/embassy-stm32/src/flash/mod.rs b/embassy-stm32/src/flash/mod.rs
index ce2d1a04c..bce638db0 100644
--- a/embassy-stm32/src/flash/mod.rs
+++ b/embassy-stm32/src/flash/mod.rs
@@ -94,6 +94,7 @@ pub enum FlashBank {
94#[cfg_attr(any(flash_l0, flash_l1, flash_l4, flash_wl, flash_wb), path = "l.rs")] 94#[cfg_attr(any(flash_l0, flash_l1, flash_l4, flash_wl, flash_wb), path = "l.rs")]
95#[cfg_attr(flash_f0, path = "f0.rs")] 95#[cfg_attr(flash_f0, path = "f0.rs")]
96#[cfg_attr(any(flash_f1, flash_f3), path = "f1f3.rs")] 96#[cfg_attr(any(flash_f1, flash_f3), path = "f1f3.rs")]
97#[cfg_attr(flash_f2, path = "f2.rs")]
97#[cfg_attr(flash_f4, path = "f4.rs")] 98#[cfg_attr(flash_f4, path = "f4.rs")]
98#[cfg_attr(flash_f7, path = "f7.rs")] 99#[cfg_attr(flash_f7, path = "f7.rs")]
99#[cfg_attr(any(flash_g0, flash_g4c2, flash_g4c3, flash_g4c4), path = "g.rs")] 100#[cfg_attr(any(flash_g0, flash_g4c2, flash_g4c3, flash_g4c4), path = "g.rs")]
@@ -104,8 +105,8 @@ pub enum FlashBank {
104#[cfg_attr(flash_u0, path = "u0.rs")] 105#[cfg_attr(flash_u0, path = "u0.rs")]
105#[cfg_attr( 106#[cfg_attr(
106 not(any( 107 not(any(
107 flash_l0, flash_l1, flash_l4, flash_wl, flash_wb, flash_f0, flash_f1, flash_f3, flash_f4, flash_f7, flash_g0, 108 flash_l0, flash_l1, flash_l4, flash_wl, flash_wb, flash_f0, flash_f1, flash_f2, flash_f3, flash_f4, flash_f7,
108 flash_g4c2, flash_g4c3, flash_g4c4, flash_h7, flash_h7ab, flash_u5, flash_h50, flash_u0 109 flash_g0, flash_g4c2, flash_g4c3, flash_g4c4, flash_h7, flash_h7ab, flash_u5, flash_h50, flash_u0
109 )), 110 )),
110 path = "other.rs" 111 path = "other.rs"
111)] 112)]