Skip to content

Commit 96df9c4

Browse files
committed
Change <Nvmc as ReadNorFlash>::READ_SIZE from 4 to 1
1 parent d81b793 commit 96df9c4

File tree

1 file changed

+58
-58
lines changed

1 file changed

+58
-58
lines changed

nrf-hal-common/src/nvmc.rs

Lines changed: 58 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::pac::NVMC;
1111
#[cfg(any(feature = "9160", feature = "5340-app"))]
1212
use crate::pac::NVMC_NS as NVMC;
1313

14+
use core::convert::TryInto;
1415
use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
1516

1617
/// Interface to an NVMC instance.
@@ -97,45 +98,37 @@ where
9798
{
9899
type Error = NvmcError;
99100

100-
const READ_SIZE: usize = 4;
101+
const READ_SIZE: usize = 1;
101102

102-
fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
103-
let offset = offset as usize;
104-
let bytes_len = bytes.len();
105-
let read_len = bytes_len + (Self::READ_SIZE - (bytes_len % Self::READ_SIZE));
106-
let target_offset = offset + read_len;
107-
if offset % Self::READ_SIZE == 0 && target_offset <= self.capacity() {
108-
self.wait_ready();
109-
let last_offset = target_offset - Self::READ_SIZE;
110-
for offset in (offset..last_offset).step_by(Self::READ_SIZE) {
111-
let word = self.storage[offset >> 2];
112-
bytes[offset] = (word >> 24) as u8;
113-
bytes[offset + 1] = (word >> 16) as u8;
114-
bytes[offset + 2] = (word >> 8) as u8;
115-
bytes[offset + 3] = (word >> 0) as u8;
116-
}
117-
let offset = last_offset;
118-
let word = self.storage[offset >> 2];
119-
let mut bytes_offset = offset;
120-
if bytes_offset < bytes_len {
121-
bytes[bytes_offset] = (word >> 24) as u8;
122-
bytes_offset += 1;
123-
if bytes_offset < bytes_len {
124-
bytes[bytes_offset] = (word >> 16) as u8;
125-
bytes_offset += 1;
126-
if bytes_offset < bytes_len {
127-
bytes[bytes_offset] = (word >> 8) as u8;
128-
bytes_offset += 1;
129-
if bytes_offset < bytes_len {
130-
bytes[bytes_offset] = (word >> 0) as u8;
131-
}
132-
}
133-
}
103+
fn read(&mut self, offset: u32, mut bytes: &mut [u8]) -> Result<(), Self::Error> {
104+
let mut offset = offset as usize;
105+
if bytes.len() > self.capacity() || offset > self.capacity() - bytes.len() {
106+
return Err(NvmcError::OutOfBounds);
107+
}
108+
self.wait_ready();
109+
if offset & 3 != 0 {
110+
let word = self.storage[offset >> 2].to_ne_bytes();
111+
let start = offset & 3;
112+
let length = 4 - start;
113+
if length > bytes.len() {
114+
bytes.copy_from_slice(&word[start..start + bytes.len()]);
115+
return Ok(());
134116
}
135-
Ok(())
136-
} else {
137-
Err(NvmcError::Unaligned)
117+
bytes[..length].copy_from_slice(&word[start..]);
118+
offset = offset + length;
119+
bytes = &mut bytes[length..];
120+
}
121+
let mut word_offset = offset >> 2;
122+
let mut chunks = bytes.chunks_exact_mut(4);
123+
for bytes in &mut chunks {
124+
bytes.copy_from_slice(&self.storage[word_offset].to_ne_bytes());
125+
word_offset += 1;
126+
}
127+
let bytes = chunks.into_remainder();
128+
if !bytes.is_empty() {
129+
bytes.copy_from_slice(&self.storage[word_offset].to_ne_bytes()[..bytes.len()]);
138130
}
131+
Ok(())
139132
}
140133

141134
fn capacity(&self) -> usize {
@@ -152,34 +145,39 @@ where
152145
const ERASE_SIZE: usize = 4 * 1024;
153146

154147
fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
155-
if from as usize % Self::ERASE_SIZE == 0 && to as usize % Self::ERASE_SIZE == 0 {
156-
self.enable_erase();
157-
for offset in (from..to).step_by(Self::ERASE_SIZE) {
158-
self.erase_page(offset as usize >> 2);
159-
}
160-
self.enable_read();
161-
Ok(())
162-
} else {
163-
Err(NvmcError::Unaligned)
148+
let from = from as usize;
149+
let to = to as usize;
150+
if from > to || to > self.capacity() {
151+
return Err(NvmcError::OutOfBounds);
152+
}
153+
if from % Self::ERASE_SIZE != 0 || to % Self::ERASE_SIZE != 0 {
154+
return Err(NvmcError::Unaligned);
155+
}
156+
self.enable_erase();
157+
for offset in (from..to).step_by(Self::ERASE_SIZE) {
158+
self.erase_page(offset);
164159
}
160+
self.enable_read();
161+
Ok(())
165162
}
166163

167164
fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
168165
let offset = offset as usize;
169-
if offset % Self::WRITE_SIZE == 0 && bytes.len() % Self::WRITE_SIZE == 0 {
170-
self.enable_write();
171-
for offset in (offset..(offset + bytes.len())).step_by(Self::WRITE_SIZE) {
172-
let word = ((bytes[offset] as u32) << 24)
173-
| ((bytes[offset + 1] as u32) << 16)
174-
| ((bytes[offset + 2] as u32) << 8)
175-
| ((bytes[offset + 3] as u32) << 0);
176-
self.write_word(offset >> 2, word);
177-
}
178-
self.enable_read();
179-
Ok(())
180-
} else {
181-
Err(NvmcError::Unaligned)
166+
if bytes.len() > self.capacity() || offset as usize > self.capacity() - bytes.len() {
167+
return Err(NvmcError::OutOfBounds);
168+
}
169+
if offset % Self::WRITE_SIZE != 0 || bytes.len() % Self::WRITE_SIZE != 0 {
170+
return Err(NvmcError::Unaligned);
171+
}
172+
self.enable_write();
173+
let mut word_offset = offset >> 2;
174+
for bytes in bytes.chunks_exact(4) {
175+
// The unwrap is correct because chunks_exact always returns the correct size.
176+
self.write_word(word_offset, u32::from_ne_bytes(bytes.try_into().unwrap()));
177+
word_offset += 1;
182178
}
179+
self.enable_read();
180+
Ok(())
183181
}
184182
}
185183

@@ -199,4 +197,6 @@ mod sealed {
199197
pub enum NvmcError {
200198
/// An operation was attempted on an unaligned boundary
201199
Unaligned,
200+
/// An operation was attempted outside the boundaries
201+
OutOfBounds,
202202
}

0 commit comments

Comments
 (0)