|
5 | 5 | // To learn about most of the ideas implemented here, check out the DMA section |
6 | 6 | // of the Embedonomicon: https://docs.rust-embedded.org/embedonomicon/dma.html |
7 | 7 |
|
| 8 | +pub use embedded_dma::{ReadBuffer, WriteBuffer}; |
| 9 | + |
8 | 10 | use crate::{ |
9 | 11 | pac::{self, dma1::ch::cr}, |
10 | 12 | rcc::AHB, |
11 | 13 | serial, |
12 | 14 | }; |
13 | 15 | use cast::u16; |
14 | 16 | use core::{ |
15 | | - mem::{self, MaybeUninit}, |
16 | | - ops::{Deref, DerefMut}, |
| 17 | + mem, |
17 | 18 | sync::atomic::{self, Ordering}, |
18 | 19 | }; |
19 | | -use stable_deref_trait::StableDeref; |
20 | 20 |
|
21 | 21 | /// Extension trait to split a DMA peripheral into independent channels |
22 | 22 | pub trait DmaExt { |
@@ -165,217 +165,6 @@ impl<B, C: Channel, T: Target> TransferInner<B, C, T> { |
165 | 165 | } |
166 | 166 | } |
167 | 167 |
|
168 | | -/// Trait for buffers that can be given to DMA for reading. |
169 | | -/// |
170 | | -/// # Safety |
171 | | -/// |
172 | | -/// The implementing type must be safe to use for DMA reads. This means: |
173 | | -/// |
174 | | -/// - It must be a pointer that references the actual buffer. |
175 | | -/// - As long as no `&mut self` method is called on the implementing object: |
176 | | -/// - `read_buffer` must always return the same value, if called multiple |
177 | | -/// times. |
178 | | -/// - The memory specified by the pointer and size returned by `read_buffer` |
179 | | -/// must not be freed as long as `self` is not dropped. |
180 | | -pub unsafe trait ReadBuffer { |
181 | | - type Word; |
182 | | - |
183 | | - /// Provide a buffer usable for DMA reads. |
184 | | - /// |
185 | | - /// The return value is: |
186 | | - /// |
187 | | - /// - pointer to the start of the buffer |
188 | | - /// - buffer size in words |
189 | | - /// |
190 | | - /// # Safety |
191 | | - /// |
192 | | - /// Once this method has been called, it is unsafe to call any `&mut self` |
193 | | - /// methods on this object as long as the returned value is in use (by DMA). |
194 | | - unsafe fn read_buffer(&self) -> (*const Self::Word, usize); |
195 | | -} |
196 | | - |
197 | | -/// Trait for buffers that can be given to DMA for writing. |
198 | | -/// |
199 | | -/// # Safety |
200 | | -/// |
201 | | -/// The implementing type must be safe to use for DMA writes. This means: |
202 | | -/// |
203 | | -/// - It must be a pointer that references the actual buffer. |
204 | | -/// - `Target` must be a type that is valid for any possible byte pattern. |
205 | | -/// - As long as no `&mut self` method, except for `write_buffer`, is called on |
206 | | -/// the implementing object: |
207 | | -/// - `write_buffer` must always return the same value, if called multiple |
208 | | -/// times. |
209 | | -/// - The memory specified by the pointer and size returned by `write_buffer` |
210 | | -/// must not be freed as long as `self` is not dropped. |
211 | | -pub unsafe trait WriteBuffer { |
212 | | - type Word; |
213 | | - |
214 | | - /// Provide a buffer usable for DMA writes. |
215 | | - /// |
216 | | - /// The return value is: |
217 | | - /// |
218 | | - /// - pointer to the start of the buffer |
219 | | - /// - buffer size in words |
220 | | - /// |
221 | | - /// # Safety |
222 | | - /// |
223 | | - /// Once this method has been called, it is unsafe to call any `&mut self` |
224 | | - /// methods, except for `write_buffer`, on this object as long as the |
225 | | - /// returned value is in use (by DMA). |
226 | | - unsafe fn write_buffer(&mut self) -> (*mut Self::Word, usize); |
227 | | -} |
228 | | - |
229 | | -// Blanked implementations for common DMA buffer types. |
230 | | - |
231 | | -unsafe impl<B, T> ReadBuffer for B |
232 | | -where |
233 | | - B: Deref<Target = T> + StableDeref, |
234 | | - T: ReadTarget + ?Sized, |
235 | | -{ |
236 | | - type Word = T::Word; |
237 | | - |
238 | | - unsafe fn read_buffer(&self) -> (*const Self::Word, usize) { |
239 | | - self.as_read_buffer() |
240 | | - } |
241 | | -} |
242 | | - |
243 | | -unsafe impl<B, T> WriteBuffer for B |
244 | | -where |
245 | | - B: DerefMut<Target = T> + StableDeref, |
246 | | - T: WriteTarget + ?Sized, |
247 | | -{ |
248 | | - type Word = T::Word; |
249 | | - |
250 | | - unsafe fn write_buffer(&mut self) -> (*mut Self::Word, usize) { |
251 | | - self.as_write_buffer() |
252 | | - } |
253 | | -} |
254 | | - |
255 | | -/// Trait for DMA word types used by the blanket DMA buffer impls. |
256 | | -/// |
257 | | -/// # Safety |
258 | | -/// |
259 | | -/// Types that implement this trait must be valid for every possible byte |
260 | | -/// pattern. This is to ensure that, whatever DMA writes into the buffer, |
261 | | -/// we won't get UB due to invalid values. |
262 | | -pub unsafe trait Word {} |
263 | | - |
264 | | -unsafe impl Word for u8 {} |
265 | | -unsafe impl Word for u16 {} |
266 | | -unsafe impl Word for u32 {} |
267 | | - |
268 | | -/// Trait for `Deref` targets used by the blanket `DmaReadBuffer` impl. |
269 | | -/// |
270 | | -/// This trait exists solely to work around |
271 | | -/// https://github.com/rust-lang/rust/issues/20400. |
272 | | -/// |
273 | | -/// # Safety |
274 | | -/// |
275 | | -/// - `as_read_buffer` must adhere to the safety requirements |
276 | | -/// documented for `DmaReadBuffer::dma_read_buffer`. |
277 | | -pub unsafe trait ReadTarget { |
278 | | - type Word: Word; |
279 | | - |
280 | | - fn as_read_buffer(&self) -> (*const Self::Word, usize) { |
281 | | - let ptr = self as *const _ as *const Self::Word; |
282 | | - let len = mem::size_of_val(self) / mem::size_of::<Self::Word>(); |
283 | | - (ptr, len) |
284 | | - } |
285 | | -} |
286 | | - |
287 | | -/// Trait for `DerefMut` targets used by the blanket `DmaWriteBuffer` impl. |
288 | | -/// |
289 | | -/// This trait exists solely to work around |
290 | | -/// https://github.com/rust-lang/rust/issues/20400. |
291 | | -/// |
292 | | -/// # Safety |
293 | | -/// |
294 | | -/// - `as_write_buffer` must adhere to the safety requirements |
295 | | -/// documented for `DmaWriteBuffer::dma_write_buffer`. |
296 | | -pub unsafe trait WriteTarget { |
297 | | - type Word: Word; |
298 | | - |
299 | | - fn as_write_buffer(&mut self) -> (*mut Self::Word, usize) { |
300 | | - let ptr = self as *mut _ as *mut Self::Word; |
301 | | - let len = mem::size_of_val(self) / mem::size_of::<Self::Word>(); |
302 | | - (ptr, len) |
303 | | - } |
304 | | -} |
305 | | - |
306 | | -unsafe impl<W: Word> ReadTarget for W { |
307 | | - type Word = W; |
308 | | -} |
309 | | - |
310 | | -unsafe impl<W: Word> WriteTarget for W { |
311 | | - type Word = W; |
312 | | -} |
313 | | - |
314 | | -unsafe impl<T: ReadTarget> ReadTarget for [T] { |
315 | | - type Word = T::Word; |
316 | | -} |
317 | | - |
318 | | -unsafe impl<T: WriteTarget> WriteTarget for [T] { |
319 | | - type Word = T::Word; |
320 | | -} |
321 | | - |
322 | | -macro_rules! dma_target_array_impls { |
323 | | - ( $( $i:expr, )+ ) => { |
324 | | - $( |
325 | | - unsafe impl<T: ReadTarget> ReadTarget for [T; $i] { |
326 | | - type Word = T::Word; |
327 | | - } |
328 | | - |
329 | | - unsafe impl<T: WriteTarget> WriteTarget for [T; $i] { |
330 | | - type Word = T::Word; |
331 | | - } |
332 | | - )+ |
333 | | - }; |
334 | | -} |
335 | | - |
336 | | -#[rustfmt::skip] |
337 | | -dma_target_array_impls!( |
338 | | - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, |
339 | | - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, |
340 | | - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, |
341 | | - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, |
342 | | - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, |
343 | | - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, |
344 | | - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, |
345 | | - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, |
346 | | - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, |
347 | | - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, |
348 | | - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, |
349 | | - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, |
350 | | - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, |
351 | | - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, |
352 | | - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, |
353 | | - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, |
354 | | - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, |
355 | | - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, |
356 | | - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, |
357 | | - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, |
358 | | - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, |
359 | | - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, |
360 | | - 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, |
361 | | - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, |
362 | | - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, |
363 | | - 250, 251, 252, 253, 254, 255, 256, |
364 | | - |
365 | | - 1 << 9, |
366 | | - 1 << 10, |
367 | | - 1 << 11, |
368 | | - 1 << 12, |
369 | | - 1 << 13, |
370 | | - 1 << 14, |
371 | | - 1 << 15, |
372 | | - 1 << 16, |
373 | | -); |
374 | | - |
375 | | -unsafe impl<T: WriteTarget> WriteTarget for MaybeUninit<T> { |
376 | | - type Word = T::Word; |
377 | | -} |
378 | | - |
379 | 168 | /// DMA address increment mode |
380 | 169 | pub enum Increment { |
381 | 170 | /// Enable increment |
|
0 commit comments