aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorokhsunrog <[email protected]>2025-05-21 01:21:43 +0300
committerokhsunrog <[email protected]>2025-05-21 01:21:43 +0300
commit7be84f137c4f56842b6ebd6de3538b0081d42a09 (patch)
tree872669c917ecc33d1bb689bc8d8f5e876ef93b62
parentd335e309012020b5eab6f0d04ee63053365140ea (diff)
eeprom support
-rw-r--r--embassy-stm32/src/flash/common.rs97
-rw-r--r--embassy-stm32/src/flash/l.rs2
2 files changed, 98 insertions, 1 deletions
diff --git a/embassy-stm32/src/flash/common.rs b/embassy-stm32/src/flash/common.rs
index 10023e637..81d8966e9 100644
--- a/embassy-stm32/src/flash/common.rs
+++ b/embassy-stm32/src/flash/common.rs
@@ -11,6 +11,9 @@ use crate::Peri;
11use crate::_generated::FLASH_BASE; 11use crate::_generated::FLASH_BASE;
12use crate::peripherals::FLASH; 12use crate::peripherals::FLASH;
13 13
14#[cfg(eeprom)]
15use crate::_generated::{EEPROM_BASE, EEPROM_SIZE};
16
14/// Internal flash memory driver. 17/// Internal flash memory driver.
15pub struct Flash<'d, MODE = Async> { 18pub struct Flash<'d, MODE = Async> {
16 pub(crate) inner: Peri<'d, FLASH>, 19 pub(crate) inner: Peri<'d, FLASH>,
@@ -72,6 +75,100 @@ impl<'d, MODE> Flash<'d, MODE> {
72 } 75 }
73} 76}
74 77
78#[cfg(eeprom)]
79impl<'d> Flash<'d, Blocking> {
80 fn eeprom_base(&self) -> u32 {
81 EEPROM_BASE as u32
82 }
83
84 fn eeprom_size(&self) -> u32 {
85 EEPROM_SIZE as u32
86 }
87
88 fn check_eeprom_offset(&self, offset: u32, size: u32) -> Result<(), Error> {
89 if offset + size > self.eeprom_size() {
90 Err(Error::Size)
91 } else {
92 Ok(())
93 }
94 }
95
96 /// Read a byte (u8) from EEPROM at the given offset.
97 pub fn eeprom_read_u8(&self, offset: u32) -> Result<u8, Error> {
98 self.check_eeprom_offset(offset, 1)?;
99 let addr = self.eeprom_base() + offset;
100 Ok(unsafe { core::ptr::read_volatile(addr as *const u8) })
101 }
102
103 /// Read a half-word (u16) from EEPROM at the given offset.
104 pub fn eeprom_read_u16(&self, offset: u32) -> Result<u16, Error> {
105 if offset % 2 != 0 {
106 return Err(Error::Unaligned);
107 }
108 self.check_eeprom_offset(offset, 2)?;
109 let addr = self.eeprom_base() + offset;
110 Ok(unsafe { core::ptr::read_volatile(addr as *const u16) })
111 }
112
113 /// Read a word (u32) from EEPROM at the given offset.
114 pub fn eeprom_read_u32(&self, offset: u32) -> Result<u32, Error> {
115 if offset % 4 != 0 {
116 return Err(Error::Unaligned);
117 }
118 self.check_eeprom_offset(offset, 4)?;
119 let addr = self.eeprom_base() + offset;
120 Ok(unsafe { core::ptr::read_volatile(addr as *const u32) })
121 }
122
123 /// Write a byte (u8) to EEPROM at the given offset.
124 pub fn eeprom_write_u8(&mut self, offset: u32, value: u8) -> Result<(), Error> {
125 self.check_eeprom_offset(offset, 1)?;
126 let addr = self.eeprom_base() + offset;
127 unsafe {
128 family::unlock();
129 core::ptr::write_volatile(addr as *mut u8, value);
130 family::wait_ready_blocking()?;
131 family::clear_all_err();
132 family::lock();
133 }
134 Ok(())
135 }
136
137 /// Write a half-word (u16) to EEPROM at the given offset.
138 pub fn eeprom_write_u16(&mut self, offset: u32, value: u16) -> Result<(), Error> {
139 if offset % 2 != 0 {
140 return Err(Error::Unaligned);
141 }
142 self.check_eeprom_offset(offset, 2)?;
143 let addr = self.eeprom_base() + offset;
144 unsafe {
145 family::unlock();
146 core::ptr::write_volatile(addr as *mut u16, value);
147 family::wait_ready_blocking()?;
148 family::clear_all_err();
149 family::lock();
150 }
151 Ok(())
152 }
153
154 /// Write a word (u32) to EEPROM at the given offset.
155 pub fn eeprom_write_u32(&mut self, offset: u32, value: u32) -> Result<(), Error> {
156 if offset % 4 != 0 {
157 return Err(Error::Unaligned);
158 }
159 self.check_eeprom_offset(offset, 4)?;
160 let addr = self.eeprom_base() + offset;
161 unsafe {
162 family::unlock();
163 core::ptr::write_volatile(addr as *mut u32, value);
164 family::wait_ready_blocking()?;
165 family::clear_all_err();
166 family::lock();
167 }
168 Ok(())
169 }
170}
171
75pub(super) fn blocking_read(base: u32, size: u32, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { 172pub(super) fn blocking_read(base: u32, size: u32, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
76 if offset + bytes.len() as u32 > size { 173 if offset + bytes.len() as u32 > size {
77 return Err(Error::Size); 174 return Err(Error::Size);
diff --git a/embassy-stm32/src/flash/l.rs b/embassy-stm32/src/flash/l.rs
index 65cea005c..1b82704ec 100644
--- a/embassy-stm32/src/flash/l.rs
+++ b/embassy-stm32/src/flash/l.rs
@@ -162,7 +162,7 @@ pub(crate) unsafe fn clear_all_err() {
162 pac::FLASH.nssr().modify(|_| {}); 162 pac::FLASH.nssr().modify(|_| {});
163} 163}
164 164
165unsafe fn wait_ready_blocking() -> Result<(), Error> { 165pub(crate) unsafe fn wait_ready_blocking() -> Result<(), Error> {
166 loop { 166 loop {
167 #[cfg(not(flash_l5))] 167 #[cfg(not(flash_l5))]
168 { 168 {