From 129b7589ca6cc3f26fd75dc860ca4a903aa9b76f Mon Sep 17 00:00:00 2001 From: TheZoq2 Date: Sat, 27 Jun 2020 11:57:47 +0200 Subject: [PATCH 1/3] Improve DMA ergonomics when working with generics --- CHANGELOG.md | 4 ++++ src/dma.rs | 25 +++++++++++++++---------- src/serial.rs | 13 ++++++++++--- src/spi.rs | 10 +++++----- 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ddf62ca..435433f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Breaking changes + +- Replace DMA buffer types with `Deref` ans `Unpin` + ## [v0.6.1] - 2020-06-25 ### Added diff --git a/src/dma.rs b/src/dma.rs index 9628587d..61677300 100644 --- a/src/dma.rs +++ b/src/dma.rs @@ -70,6 +70,11 @@ pub trait TransferPayload { fn stop(&mut self); } +pub trait Transferable { + fn is_done(&self) -> bool; + fn wait(self) -> (BUFFER, DMA); +} + pub struct Transfer { _mode: PhantomData, buffer: BUFFER, @@ -128,7 +133,7 @@ macro_rules! dma { use crate::pac::{$DMAX, dma1}; - use crate::dma::{CircBuffer, DmaExt, Error, Event, Half, Transfer, W, RxDma, TxDma, TransferPayload}; + use crate::dma::{CircBuffer, DmaExt, Error, Event, Half, Transfer, W, RxDma, TxDma, TransferPayload, Transferable}; use crate::rcc::{AHB, Enable}; pub struct Channels((), $(pub $CX),+); @@ -294,15 +299,15 @@ macro_rules! dma { } } - impl Transfer> + impl Transferable> for Transfer> where RxDma: TransferPayload, { - pub fn is_done(&self) -> bool { + fn is_done(&self) -> bool { !self.payload.channel.in_progress() } - pub fn wait(mut self) -> (BUFFER, RxDma) { + fn wait(mut self) -> (BUFFER, RxDma) { while !self.is_done() {} atomic::compiler_fence(Ordering::Acquire); @@ -320,15 +325,15 @@ macro_rules! dma { } } - impl Transfer> + impl Transferable> for Transfer> where TxDma: TransferPayload, { - pub fn is_done(&self) -> bool { + fn is_done(&self) -> bool { !self.payload.channel.in_progress() } - pub fn wait(mut self) -> (BUFFER, TxDma) { + fn wait(mut self) -> (BUFFER, TxDma) { while !self.is_done() {} atomic::compiler_fence(Ordering::Acquire); @@ -496,10 +501,10 @@ where fn read(self, buffer: &'static mut B) -> Transfer; } -pub trait WriteDma: Transmit +pub trait WriteDma: Transmit where - A: as_slice::AsSlice, - B: Static, + B: core::ops::Deref + 'static, + B::Target: as_slice::AsSlice + Unpin, Self: core::marker::Sized, { fn write(self, buffer: B) -> Transfer; diff --git a/src/serial.rs b/src/serial.rs index f8b5d2de..f9d4c28d 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -44,10 +44,13 @@ use core::sync::atomic::{self, Ordering}; use crate::pac::{USART1, USART2, USART3}; use core::convert::Infallible; + +use as_slice::AsSlice; + use embedded_hal::serial::Write; use crate::afio::MAPR; -use crate::dma::{dma1, CircBuffer, RxDma, Static, Transfer, TxDma, R, W}; +use crate::dma::{dma1, CircBuffer, RxDma, Transfer, TxDma, R, W}; use crate::gpio::gpioa::{PA10, PA2, PA3, PA9}; use crate::gpio::gpiob::{PB10, PB11, PB6, PB7}; use crate::gpio::gpioc::{PC10, PC11}; @@ -637,12 +640,16 @@ macro_rules! serialdma { } } - impl crate::dma::WriteDma for $txdma where A: as_slice::AsSlice, B: Static { + impl crate::dma::WriteDma for $txdma + where + B: core::ops::Deref + 'static, + B::Target: AsSlice + Unpin, + { fn write(mut self, buffer: B ) -> Transfer { { - let buffer = buffer.borrow().as_slice(); + let buffer = (*buffer).as_slice(); self.channel.set_peripheral_address(unsafe{ &(*$USARTX::ptr()).dr as *const _ as u32 }, false); diff --git a/src/spi.rs b/src/spi.rs index b7363ac8..009f919f 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -41,7 +41,7 @@ use crate::pac::{SPI1, SPI2}; use crate::afio::MAPR; use crate::dma::dma1::{C3, C5}; -use crate::dma::{Static, Transfer, TransferPayload, Transmit, TxDma, R}; +use crate::dma::{Transfer, TransferPayload, Transmit, TxDma, R}; use crate::gpio::gpioa::{PA5, PA6, PA7}; use crate::gpio::gpiob::{PB13, PB14, PB15, PB3, PB4, PB5}; #[cfg(feature = "connectivity")] @@ -450,14 +450,14 @@ macro_rules! spi_dma { } } - impl crate::dma::WriteDma for SpiTxDma<$SPIi, REMAP, PIN, $TCi> + impl crate::dma::WriteDma for SpiTxDma<$SPIi, REMAP, PIN, $TCi> where - A: AsSlice, - B: Static, + B: core::ops::Deref + 'static, + B::Target: as_slice::AsSlice + Unpin, { fn write(mut self, buffer: B) -> Transfer { { - let buffer = buffer.borrow().as_slice(); + let buffer = buffer.as_slice(); self.channel.set_peripheral_address( unsafe { &(*$SPIi::ptr()).dr as *const _ as u32 }, false, From 701eaee717c8a34b8bc9780648ae2d57a4ffea3c Mon Sep 17 00:00:00 2001 From: TheZoq2 Date: Sun, 28 Jun 2020 10:03:29 +0200 Subject: [PATCH 2/3] Add stable deref bound --- Cargo.toml | 4 ++++ src/dma.rs | 3 +++ src/serial.rs | 3 ++- src/spi.rs | 3 ++- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c71c8a2e..ba03ac53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,10 @@ version = "0.2.2" version = "0.2.3" features = ["unproven"] +[dependencies.stable_deref_trait] +default-features = false +version = "1.1" + [dependencies.stm32-usbd] version = "0.5.0" features = ["ram_access_1x16"] diff --git a/src/dma.rs b/src/dma.rs index 61677300..20e0e1c9 100644 --- a/src/dma.rs +++ b/src/dma.rs @@ -4,6 +4,8 @@ use core::marker::PhantomData; use core::ops; +use stable_deref_trait::StableDeref; + use crate::rcc::AHB; #[derive(Debug)] @@ -505,6 +507,7 @@ pub trait WriteDma: Transmit where B: core::ops::Deref + 'static, B::Target: as_slice::AsSlice + Unpin, + B: StableDeref, Self: core::marker::Sized, { fn write(self, buffer: B) -> Transfer; diff --git a/src/serial.rs b/src/serial.rs index f9d4c28d..160679b9 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -46,6 +46,7 @@ use crate::pac::{USART1, USART2, USART3}; use core::convert::Infallible; use as_slice::AsSlice; +use stable_deref_trait::StableDeref; use embedded_hal::serial::Write; @@ -642,7 +643,7 @@ macro_rules! serialdma { impl crate::dma::WriteDma for $txdma where - B: core::ops::Deref + 'static, + B: StableDeref + core::ops::Deref + 'static, B::Target: AsSlice + Unpin, { fn write(mut self, buffer: B diff --git a/src/spi.rs b/src/spi.rs index 009f919f..4231a559 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -53,6 +53,7 @@ use crate::time::Hertz; use core::sync::atomic::{self, Ordering}; use as_slice::AsSlice; +use stable_deref_trait::StableDeref; /// SPI error #[derive(Debug)] @@ -452,7 +453,7 @@ macro_rules! spi_dma { impl crate::dma::WriteDma for SpiTxDma<$SPIi, REMAP, PIN, $TCi> where - B: core::ops::Deref + 'static, + B: StableDeref + core::ops::Deref + 'static, B::Target: as_slice::AsSlice + Unpin, { fn write(mut self, buffer: B) -> Transfer { From 05e0821269d4a08ca673547fbeaeca9cde91d24c Mon Sep 17 00:00:00 2001 From: TheZoq2 Date: Sun, 28 Jun 2020 10:09:21 +0200 Subject: [PATCH 3/3] Cargo fmt --- src/dma.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dma.rs b/src/dma.rs index 20e0e1c9..61edd0fc 100644 --- a/src/dma.rs +++ b/src/dma.rs @@ -506,7 +506,7 @@ where pub trait WriteDma: Transmit where B: core::ops::Deref + 'static, - B::Target: as_slice::AsSlice + Unpin, + B::Target: as_slice::AsSlice + Unpin, B: StableDeref, Self: core::marker::Sized, {