|
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