1use alloc::vec;
9use alloc::vec::Vec;
10
11use embedded_storage::nor_flash::{
12 ErrorType,
13 NorFlash,
14 NorFlashError,
15 NorFlashErrorKind,
16 ReadNorFlash,
17};
18
19use crate::FLASH_SECTOR_SIZE;
20use crate::platform::{
21 Crc,
22 software_crc32,
23};
24
25const WORD_SIZE: usize = 4;
26
27pub struct MemFlash {
35 buf: Vec<u8>,
36}
37
38impl MemFlash {
39 pub fn new(pages: usize) -> Self {
41 Self {
42 buf: vec![0xFF; FLASH_SECTOR_SIZE * pages],
43 }
44 }
45
46 pub fn from_bytes(data: Vec<u8>) -> Self {
53 assert!(
54 data.len().is_multiple_of(FLASH_SECTOR_SIZE),
55 "MemFlash data length {} is not a multiple of sector size {}",
56 data.len(),
57 FLASH_SECTOR_SIZE
58 );
59 Self { buf: data }
60 }
61
62 pub fn into_inner(self) -> Vec<u8> {
64 self.buf
65 }
66
67 pub fn len(&self) -> usize {
69 self.buf.len()
70 }
71
72 pub fn is_empty(&self) -> bool {
74 self.buf.is_empty()
75 }
76}
77
78#[derive(Debug)]
79pub struct MemFlashError;
80
81impl NorFlashError for MemFlashError {
82 fn kind(&self) -> NorFlashErrorKind {
83 NorFlashErrorKind::Other
84 }
85}
86
87impl ErrorType for MemFlash {
88 type Error = MemFlashError;
89}
90
91impl ReadNorFlash for MemFlash {
92 const READ_SIZE: usize = WORD_SIZE;
93
94 fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
95 let offset = offset as usize;
96 bytes.copy_from_slice(&self.buf[offset..offset + bytes.len()]);
97 Ok(())
98 }
99
100 fn capacity(&self) -> usize {
101 self.buf.len()
102 }
103}
104
105impl NorFlash for MemFlash {
106 const WRITE_SIZE: usize = WORD_SIZE;
107 const ERASE_SIZE: usize = FLASH_SECTOR_SIZE;
108
109 fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
110 for addr in from..to {
111 self.buf[addr as usize] = 0xFF;
112 }
113 Ok(())
114 }
115
116 fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
117 let offset = offset as usize;
118 for (i, &val) in bytes.iter().enumerate() {
119 self.buf[offset + i] &= val;
121 }
122 Ok(())
123 }
124}
125
126impl Crc for MemFlash {
127 fn crc32(init: u32, data: &[u8]) -> u32 {
128 software_crc32(init, data)
129 }
130}