1use crate::ll_api::{FlashOperate, ll_cmd::*};
2use core::marker::PhantomData;
3use embedded_storage::{
4 self,
5 nor_flash::{NorFlashError, NorFlashErrorKind},
6};
7
8pub const READ_SIZE: usize = 1;
9
10pub enum Blocking {}
12
13#[allow(missing_docs)]
19#[derive(Debug, Copy, Clone, PartialEq, Eq)]
20#[cfg_attr(feature = "defmt", derive(defmt::Format))]
21pub enum Error {
22 Prog,
23 Size,
24 Miss,
25 Seq,
26 Protected,
27 Unaligned,
28 Parallelism,
29 Other,
30}
31
32impl From<i32> for Error {
33 fn from(value: i32) -> Self {
34 match value {
35 -1 => Self::Prog,
36 -2 => Self::Size,
37 -3 => Self::Miss,
38 -4 => Self::Seq,
39 -5 => Self::Protected,
40 -6 => Self::Unaligned,
41 -7 => Self::Parallelism,
42 _ => Self::Other,
43 }
44 }
45}
46
47impl NorFlashError for Error {
48 fn kind(&self) -> NorFlashErrorKind {
49 match self {
50 Self::Size => NorFlashErrorKind::OutOfBounds,
51 Self::Unaligned => NorFlashErrorKind::NotAligned,
52 _ => NorFlashErrorKind::Other,
53 }
54 }
55}
56
57pub struct Flash<
59 const PAGE_SIZE: usize,
60 const PAGE_NUM: usize,
61 const MINI_WRITE_SIZE: usize = 4,
62 const MINI_READ_SIZE: usize = 1,
63 MODE = Blocking,
64> {
65 pub(crate) _mode: PhantomData<MODE>,
66}
67
68impl<
69 const PAGE_SIZE: usize,
70 const PAGE_NUM: usize,
71 const MINI_WRITE_SIZE: usize,
72 const MINI_READ_SIZE: usize,
73> Flash<PAGE_SIZE, PAGE_NUM, MINI_WRITE_SIZE, MINI_READ_SIZE, Blocking>
74{
75 pub fn new_blocking() -> Self {
77 Self { _mode: PhantomData }
78 }
79}
80
81impl<
82 const PAGE_SIZE: usize,
83 const PAGE_NUM: usize,
84 const MINI_WRITE_SIZE: usize,
85 const MINI_READ_SIZE: usize,
86 MODE,
87> Flash<PAGE_SIZE, PAGE_NUM, MINI_WRITE_SIZE, MINI_READ_SIZE, MODE>
88{
89 pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
94 let result = ll_invoke_inner!(
95 INVOKE_ID_FLASH_OPERATE,
96 FlashOperate::Read,
97 offset,
98 bytes.as_mut_ptr(),
99 bytes.len()
100 );
101 if result < 0 {
102 return Err(result.into());
103 }
104
105 Ok(())
106 }
107
108 pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> {
113 let result = ll_invoke_inner!(
114 INVOKE_ID_FLASH_OPERATE,
115 FlashOperate::Write,
116 offset,
117 bytes.as_ptr(),
118 bytes.len()
119 );
120 if result < 0 {
121 return Err(result.into());
122 }
123
124 Ok(())
125 }
126
127 pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> {
132 let result = ll_invoke_inner!(INVOKE_ID_FLASH_OPERATE, FlashOperate::Erase, from, to);
133 if result < 0 {
134 return Err(result.into());
135 }
136 Ok(())
137 }
138}
139
140impl<
141 const PAGE_SIZE: usize,
142 const PAGE_NUM: usize,
143 const MINI_WRITE_SIZE: usize,
144 const MINI_READ_SIZE: usize,
145 MODE,
146> embedded_storage::nor_flash::ErrorType
147 for Flash<PAGE_SIZE, PAGE_NUM, MINI_WRITE_SIZE, MINI_READ_SIZE, MODE>
148{
149 type Error = Error;
150}
151
152impl<
153 const PAGE_SIZE: usize,
154 const PAGE_NUM: usize,
155 const MINI_WRITE_SIZE: usize,
156 const MINI_READ_SIZE: usize,
157 MODE,
158> embedded_storage::nor_flash::ReadNorFlash
159 for Flash<PAGE_SIZE, PAGE_NUM, MINI_WRITE_SIZE, MINI_READ_SIZE, MODE>
160{
161 const READ_SIZE: usize = MINI_READ_SIZE;
162
163 fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
164 self.blocking_read(offset, bytes)
165 }
166
167 fn capacity(&self) -> usize {
168 PAGE_SIZE * PAGE_NUM
169 }
170}
171
172impl<
173 const PAGE_SIZE: usize,
174 const PAGE_NUM: usize,
175 const MINI_WRITE_SIZE: usize,
176 const MINI_READ_SIZE: usize,
177 MODE,
178> embedded_storage::nor_flash::NorFlash
179 for Flash<PAGE_SIZE, PAGE_NUM, MINI_WRITE_SIZE, MINI_READ_SIZE, MODE>
180{
181 const WRITE_SIZE: usize = MINI_WRITE_SIZE;
182 const ERASE_SIZE: usize = PAGE_SIZE;
183
184 fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
185 self.blocking_write(offset, bytes)
186 }
187
188 fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
189 self.blocking_erase(from, to)
190 }
191}