Skip to content

Commit 5fd4c3b

Browse files
Improve Readability of Write And Erase Methods
Add Doc Comment To CAPACITY const
1 parent d3ef316 commit 5fd4c3b

File tree

1 file changed

+101
-60
lines changed

1 file changed

+101
-60
lines changed

hal/src/efc.rs

Lines changed: 101 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -31,39 +31,71 @@ pub enum VddioLevel {
3131
pub const BASE_ADDRESS: u32 = 0x00400000;
3232
///The Capacity in bytes of the Flash Memory.
3333
#[cfg(feature = "flash-2M")]
34-
pub const CAPACITY: usize = 0x00200000;
34+
pub const CAPACITY: u32 = 0x00200000;
35+
///The Capacity in bytes of the Flash Memory.
3536
#[cfg(feature = "flash-1M")]
36-
pub const CAPACITY: usize = 0x00100000;
37+
pub const CAPACITY: u32 = 0x00100000;
38+
///The Capacity in bytes of the Flash Memory.
3739
#[cfg(feature = "flash-512K")]
38-
pub const CAPACITY: usize = 0x00080000;
40+
pub const CAPACITY: u32 = 0x00080000;
3941
/// The Size in bytes of a page in the Flash Memory.
40-
pub const PAGE_SIZE: usize = 512;
42+
pub const PAGE_SIZE: u32 = 512;
4143
/// The Size in bytes of a sector in the Flash Memory.
42-
pub const SECTOR_SIZE: usize = 0x00020000;
44+
pub const SECTOR_SIZE: u32 = 0x00020000;
4345

4446
/// An iterator over the Flash Sectors.
4547
struct SectorIterator {
46-
index: u8,
47-
number_of_sectors: u8,
48+
start_offset: u32,
49+
end_offset: u32,
4850
}
4951

5052
/// A struct representing a Sector in Flash Memory.
5153
#[derive(Clone, Copy)]
5254
struct Sector {
53-
n: u8,
55+
offset: u32,
5456
}
5557

5658
impl Iterator for SectorIterator {
5759
type Item = Sector;
5860

5961
fn next(&mut self) -> Option<Self::Item> {
60-
self.index += 1;
62+
if self.start_offset >= self.end_offset {
63+
return None;
64+
}
65+
let sector = Sector {
66+
offset: self.start_offset,
67+
};
68+
self.start_offset += SECTOR_SIZE;
6169

62-
if self.index < self.number_of_sectors {
63-
Some(Sector { n: self.index })
64-
} else {
65-
None
70+
Some(sector)
71+
}
72+
}
73+
74+
/// A struct representing a Page in Flash memory
75+
#[derive(Clone, Copy)]
76+
struct Page {
77+
offset: u32,
78+
}
79+
80+
/// An iterator over the Flash Pages.
81+
struct PageIterator {
82+
start_offset: u32,
83+
end_offset: u32,
84+
}
85+
86+
impl Iterator for PageIterator {
87+
type Item = Page;
88+
89+
fn next(&mut self) -> Option<Self::Item> {
90+
if self.start_offset >= self.end_offset {
91+
return None;
6692
}
93+
let page = Page {
94+
offset: self.start_offset,
95+
};
96+
self.start_offset += PAGE_SIZE;
97+
98+
Some(page)
6799
}
68100
}
69101

@@ -146,7 +178,7 @@ impl Sector {
146178
self.efc().eefc_fcr.write(|w| {
147179
w.fkey().passwd();
148180
w.fcmd().es();
149-
unsafe { w.farg().bits((256_u16 * (self.n as u16)) as u16) };
181+
unsafe { w.farg().bits(self.page_number()) };
150182
w
151183
});
152184
loop {
@@ -162,24 +194,37 @@ impl Sector {
162194
}
163195
}
164196

197+
// #[inline(always)] fn addr(&self) -> *mut u8 {
198+
// (BASE_ADDRESS + self.offset) as *mut u8
199+
// }
200+
201+
#[inline(always)]
202+
fn page_number(&self) -> u16 {
203+
(self.offset / PAGE_SIZE) as u16
204+
}
205+
206+
// #[inline(always)]
207+
// fn contains(&self, offset: u32) -> bool {
208+
// offset >= self.offset
209+
// && offset < self.offset + SECTOR_SIZE
210+
// }
211+
}
212+
213+
impl Page {
165214
/// Write page to flash memory.
166-
fn write_page(&self, page: u8, data: &[u8]) -> Result<(), Error> {
167-
if data.len() != PAGE_SIZE {
215+
fn write_page(&self, data: &[u8]) -> Result<(), Error> {
216+
if data.len() != PAGE_SIZE as usize {
168217
return Err(Error::NotAligned);
169218
}
170219
if self.efc().eefc_fsr.read().frdy().bit_is_clear() {
171220
return Err(Error::FlashBusyError);
172221
}
173-
unsafe {
174-
self.addr()
175-
.add((page as usize) * PAGE_SIZE)
176-
.copy_from(data.as_ptr(), PAGE_SIZE)
177-
};
222+
unsafe { self.addr().copy_from(data.as_ptr(), PAGE_SIZE as usize) };
178223

179224
self.efc().eefc_fcr.write(|w| {
180225
w.fkey().passwd();
181226
w.fcmd().wp();
182-
unsafe { w.farg().bits(256_u16 * (self.n as u16) + (page as u16)) };
227+
unsafe { w.farg().bits(self.page_number()) };
183228
w
184229
});
185230
loop {
@@ -197,15 +242,20 @@ impl Sector {
197242

198243
#[inline(always)]
199244
fn addr(&self) -> *mut u8 {
200-
(BASE_ADDRESS as usize + (self.n as usize) * SECTOR_SIZE) as *mut u8
245+
(BASE_ADDRESS + self.offset) as *mut u8
201246
}
202247

203248

204249
#[inline(always)]
205-
fn contains(&self, offset: u32) -> bool {
206-
offset >= SECTOR_SIZE as u32 * self.n as u32
207-
&& offset < SECTOR_SIZE as u32 * (self.n as u32 + 1)
250+
fn page_number(&self) -> u16 {
251+
(self.offset / PAGE_SIZE) as u16
208252
}
253+
254+
// #[inline(always)]
255+
// fn contains(&self, offset: u32) -> bool {
256+
// offset >= self.offset
257+
// && offset < self.offset + PAGE_SIZE as u32
258+
// }
209259
}
210260

211261
trait RegisterAccess {
@@ -215,6 +265,7 @@ trait RegisterAccess {
215265
}
216266

217267
impl RegisterAccess for Sector {}
268+
impl RegisterAccess for Page {}
218269
/// [`EFC`] abstraction.
219270
pub struct Efc {
220271
pub(crate) periph: EFC,
@@ -252,22 +303,34 @@ impl Efc {
252303

253304
trait Flash {
254305
type SectorIterator;
255-
fn len(&self) -> usize {
306+
type PageIterator;
307+
308+
fn len(&self) -> u32 {
256309
CAPACITY
257310
}
311+
258312
fn address(&self) -> u32 {
259313
BASE_ADDRESS
260314
}
261-
fn sectors() -> SectorIterator {
315+
316+
fn sectors(start_offset: u32, end_offset: u32) -> SectorIterator {
262317
SectorIterator {
263-
index: 0,
264-
number_of_sectors: (CAPACITY / SECTOR_SIZE) as u8,
318+
start_offset,
319+
end_offset,
320+
}
321+
}
322+
323+
fn pages(start_offset: u32, end_offset: u32) -> PageIterator {
324+
PageIterator {
325+
start_offset,
326+
end_offset,
265327
}
266328
}
267329
}
268330

269331
impl Flash for Efc {
270332
type SectorIterator = SectorIterator;
333+
type PageIterator = PageIterator;
271334
}
272335

273336
impl ErrorType for Efc {
@@ -288,52 +351,30 @@ impl ReadNorFlash for Efc {
288351
}
289352

290353
fn capacity(&self) -> usize {
291-
self.len()
354+
self.len() as usize
292355
}
293356
}
294357

295358
impl NorFlash for Efc {
296-
const WRITE_SIZE: usize = PAGE_SIZE;
359+
const WRITE_SIZE: usize = PAGE_SIZE as usize;
297360
// NOTE: This number is the sector size, there is an option to erase by page as well, but the
298361
// minimum/maximum erase size for that varies throughout the flash memory.
299-
const ERASE_SIZE: usize = SECTOR_SIZE;
362+
const ERASE_SIZE: usize = SECTOR_SIZE as usize;
300363

301364
fn erase(&mut self, offset: u32, to: u32) -> Result<(), Self::Error> {
302365
check_erase(self, offset, to)?;
303-
let mut offset = offset;
304-
for sector in Self::sectors() {
305-
if sector.contains(offset) {
306-
sector.erase_sector()?;
307-
offset += Self::ERASE_SIZE as u32;
308-
}
309-
if offset >= to {
310-
break;
311-
}
366+
for sector in Self::sectors(offset, to) {
367+
sector.erase_sector()?;
312368
}
313369
Ok(())
314370
}
315371

316372
fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
317373
check_write(self, offset, bytes.len())?;
318-
let mut offset = offset;
319374
let mut bytes_written = 0;
320-
for sector in Self::sectors() {
321-
while sector.contains(offset) {
322-
let sector_offset = sector.n as usize * SECTOR_SIZE;
323-
let page = ((offset as usize - sector_offset) / Self::WRITE_SIZE) as u8;
324-
sector.write_page(
325-
page,
326-
&bytes[bytes_written..(bytes_written + Self::WRITE_SIZE)],
327-
)?;
328-
bytes_written += Self::WRITE_SIZE;
329-
offset += Self::WRITE_SIZE as u32;
330-
if bytes_written >= bytes.len() {
331-
break;
332-
}
333-
}
334-
if bytes_written >= bytes.len() {
335-
break;
336-
}
375+
for page in Self::pages(offset, offset + bytes.len() as u32) {
376+
page.write_page(&bytes[bytes_written..(bytes_written + Self::WRITE_SIZE)])?;
377+
bytes_written += Self::WRITE_SIZE;
337378
}
338379
Ok(())
339380
}

0 commit comments

Comments
 (0)