aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias <[email protected]>2022-10-27 07:10:27 +0200
committerMathias <[email protected]>2022-10-27 07:10:35 +0200
commit3c6c382465131c6f76567f976198b77e327df4b2 (patch)
tree570c0cbf8b69fbc22c6ff81102d0cab31a9d84e9
parent1669e395654430dff6dffda0cef9522f9ccfd213 (diff)
Remove random delay from example, and move flash functions to allow using without embedded-storage in scope
-rw-r--r--embassy-rp/src/flash.rs120
-rw-r--r--examples/rp/src/bin/flash.rs8
2 files changed, 74 insertions, 54 deletions
diff --git a/embassy-rp/src/flash.rs b/embassy-rp/src/flash.rs
index 0f86684e2..d09cc62fb 100644
--- a/embassy-rp/src/flash.rs
+++ b/embassy-rp/src/flash.rs
@@ -55,51 +55,10 @@ pub struct Flash<'d, T: Instance, const FLASH_SIZE: usize>(PhantomData<&'d mut T
55 55
56impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { 56impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> {
57 pub fn new(_flash: impl Peripheral<P = T> + 'd) -> Self { 57 pub fn new(_flash: impl Peripheral<P = T> + 'd) -> Self {
58 // FIXME: WHY is this needed?!
59 cortex_m::asm::delay(50_000);
60 Self(PhantomData) 58 Self(PhantomData)
61 } 59 }
62 60
63 /// Make sure to uphold the contract points with rp2040-flash. 61 pub fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
64 /// - interrupts must be disabled
65 /// - DMA must not access flash memory
66 unsafe fn in_ram(&mut self, operation: impl FnOnce()) {
67 let dma_status = &mut [false; crate::dma::CHANNEL_COUNT];
68
69 // TODO: Make sure CORE1 is paused during the entire duration of the RAM function
70
71 critical_section::with(|_| {
72 // Pause all DMA channels for the duration of the ram operation
73 for (number, status) in dma_status.iter_mut().enumerate() {
74 let ch = crate::pac::DMA.ch(number as _);
75 *status = ch.ctrl_trig().read().en();
76 if *status {
77 ch.ctrl_trig().modify(|w| w.set_en(false));
78 }
79 }
80
81 // Run our flash operation in RAM
82 operation();
83
84 // Re-enable previously enabled DMA channels
85 for (number, status) in dma_status.iter().enumerate() {
86 let ch = crate::pac::DMA.ch(number as _);
87 if *status {
88 ch.ctrl_trig().modify(|w| w.set_en(true));
89 }
90 }
91 });
92 }
93}
94
95impl<'d, T: Instance, const FLASH_SIZE: usize> ErrorType for Flash<'d, T, FLASH_SIZE> {
96 type Error = Error;
97}
98
99impl<'d, T: Instance, const FLASH_SIZE: usize> ReadNorFlash for Flash<'d, T, FLASH_SIZE> {
100 const READ_SIZE: usize = READ_SIZE;
101
102 fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
103 check_read(self, offset, bytes.len())?; 62 check_read(self, offset, bytes.len())?;
104 63
105 let flash_data = unsafe { core::slice::from_raw_parts((FLASH_BASE as u32 + offset) as *const u8, bytes.len()) }; 64 let flash_data = unsafe { core::slice::from_raw_parts((FLASH_BASE as u32 + offset) as *const u8, bytes.len()) };
@@ -108,19 +67,11 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> ReadNorFlash for Flash<'d, T, FLA
108 Ok(()) 67 Ok(())
109 } 68 }
110 69
111 fn capacity(&self) -> usize { 70 pub fn capacity(&self) -> usize {
112 FLASH_SIZE 71 FLASH_SIZE
113 } 72 }
114}
115 73
116impl<'d, T: Instance, const FLASH_SIZE: usize> MultiwriteNorFlash for Flash<'d, T, FLASH_SIZE> {} 74 pub fn erase(&mut self, from: u32, to: u32) -> Result<(), Error> {
117
118impl<'d, T: Instance, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, FLASH_SIZE> {
119 const WRITE_SIZE: usize = WRITE_SIZE;
120
121 const ERASE_SIZE: usize = ERASE_SIZE;
122
123 fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
124 check_erase(self, from, to)?; 75 check_erase(self, from, to)?;
125 76
126 trace!( 77 trace!(
@@ -136,7 +87,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, FLASH_S
136 Ok(()) 87 Ok(())
137 } 88 }
138 89
139 fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> { 90 pub fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> {
140 check_write(self, offset, bytes.len())?; 91 check_write(self, offset, bytes.len())?;
141 92
142 trace!("Writing {:?} bytes to 0x{:x}", bytes.len(), FLASH_BASE as u32 + offset); 93 trace!("Writing {:?} bytes to 0x{:x}", bytes.len(), FLASH_BASE as u32 + offset);
@@ -199,6 +150,69 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, FLASH_S
199 150
200 Ok(()) 151 Ok(())
201 } 152 }
153
154 /// Make sure to uphold the contract points with rp2040-flash.
155 /// - interrupts must be disabled
156 /// - DMA must not access flash memory
157 unsafe fn in_ram(&mut self, operation: impl FnOnce()) {
158 let dma_status = &mut [false; crate::dma::CHANNEL_COUNT];
159
160 // TODO: Make sure CORE1 is paused during the entire duration of the RAM function
161
162 critical_section::with(|_| {
163 // Pause all DMA channels for the duration of the ram operation
164 for (number, status) in dma_status.iter_mut().enumerate() {
165 let ch = crate::pac::DMA.ch(number as _);
166 *status = ch.ctrl_trig().read().en();
167 if *status {
168 ch.ctrl_trig().modify(|w| w.set_en(false));
169 }
170 }
171
172 // Run our flash operation in RAM
173 operation();
174
175 // Re-enable previously enabled DMA channels
176 for (number, status) in dma_status.iter().enumerate() {
177 let ch = crate::pac::DMA.ch(number as _);
178 if *status {
179 ch.ctrl_trig().modify(|w| w.set_en(true));
180 }
181 }
182 });
183 }
184}
185
186impl<'d, T: Instance, const FLASH_SIZE: usize> ErrorType for Flash<'d, T, FLASH_SIZE> {
187 type Error = Error;
188}
189
190impl<'d, T: Instance, const FLASH_SIZE: usize> ReadNorFlash for Flash<'d, T, FLASH_SIZE> {
191 const READ_SIZE: usize = READ_SIZE;
192
193 fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> {
194 self.read(offset, bytes)
195 }
196
197 fn capacity(&self) -> usize {
198 self.capacity()
199 }
200}
201
202impl<'d, T: Instance, const FLASH_SIZE: usize> MultiwriteNorFlash for Flash<'d, T, FLASH_SIZE> {}
203
204impl<'d, T: Instance, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, FLASH_SIZE> {
205 const WRITE_SIZE: usize = WRITE_SIZE;
206
207 const ERASE_SIZE: usize = ERASE_SIZE;
208
209 fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> {
210 self.erase(from, to)
211 }
212
213 fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> {
214 self.write(offset, bytes)
215 }
202} 216}
203 217
204#[allow(dead_code)] 218#[allow(dead_code)]
diff --git a/examples/rp/src/bin/flash.rs b/examples/rp/src/bin/flash.rs
index d4dfca759..8d6b379f4 100644
--- a/examples/rp/src/bin/flash.rs
+++ b/examples/rp/src/bin/flash.rs
@@ -6,7 +6,7 @@ use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_rp::flash::{ERASE_SIZE, FLASH_BASE}; 7use embassy_rp::flash::{ERASE_SIZE, FLASH_BASE};
8use embassy_rp::peripherals::FLASH; 8use embassy_rp::peripherals::FLASH;
9use embedded_storage::nor_flash::{NorFlash, ReadNorFlash}; 9use embassy_time::{Duration, Timer};
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
11 11
12const ADDR_OFFSET: u32 = 0x100000; 12const ADDR_OFFSET: u32 = 0x100000;
@@ -17,6 +17,12 @@ async fn main(_spawner: Spawner) {
17 let p = embassy_rp::init(Default::default()); 17 let p = embassy_rp::init(Default::default());
18 info!("Hello World!"); 18 info!("Hello World!");
19 19
20 // add some delay to give an attached debug probe time to parse the
21 // defmt RTT header. Reading that header might touch flash memory, which
22 // interferes with flash write operations.
23 // https://github.com/knurling-rs/defmt/pull/683
24 Timer::after(Duration::from_millis(10)).await;
25
20 let mut flash = embassy_rp::flash::Flash::<_, FLASH_SIZE>::new(p.FLASH); 26 let mut flash = embassy_rp::flash::Flash::<_, FLASH_SIZE>::new(p.FLASH);
21 erase_write_sector(&mut flash, 0x00); 27 erase_write_sector(&mut flash, 0x00);
22 28