Struct stm32f412g::dma::Dma1

source ·
pub struct Dma1<'a> { /* private fields */ }
Expand description

Dma1 is kept as a separate type from Dma2 in order to allow for more compile-time checks.

Excerpt from the discussion on this decision:

It’s definitely a tradeoff between having code duplication vs. more checks at compile time. With the current implementation the Dma is propagated to the types of Usart & SPI, so usart1 is a Usart<Dma2>. In theory, we could simply have a single DmaPeripheral enum, that contains all peripherals, with a single, non-generic Stream struct implementation. This way we wouldn’t have any code duplication and both Usart and Spi would no longer have to be generic over the Dma or its peripheral. The disadvantage then would be, that one could create a Usart instance for usart1 and accidentally pass it a stream of dma1, instead of dma2. Currently, this is impossible, as they are of different types.

We could have these checks at runtime, with the Peripheral reporting which Dma it belongs to and the system panicking if it’s set up incorrectly, like I have added for checking whether the peripheral is added to the right stream.

So we basically have three options here:

  1. Keep Stream<DmaX>
  2. Change to Stream<DmaXPeripheral>
  3. Remove Generics from Stream & add runtime checks

In order of most code duplication & compile-time safety to least.

The decision to stick with separate types for DMA 1 and DMA 2 was made because:

Static checks are good, and the code duplication here looks manageable (i.e. it’s pretty formulaic and unlikely to need to change much if at all).

For details, see the full discussion.

Implementations§

source§

impl<'a> Dma1<'a>

source

pub const fn new(clocks: &'a dyn Stm32f4Clocks) -> Dma1<'a>

source

pub fn is_enabled_clock(&self) -> bool

source

pub fn enable_clock(&self)

source

pub fn disable_clock(&self)

Trait Implementations§

source§

impl<'a> StreamClient<'a, Dma1<'a>> for Spi<'a>

source§

impl<'a> StreamClient<'a, Dma1<'a>> for Usart<'a, Dma1<'a>>

source§

impl<'a> StreamServer<'a> for Dma1<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for Dma1<'a>

§

impl<'a> !RefUnwindSafe for Dma1<'a>

§

impl<'a> !Send for Dma1<'a>

§

impl<'a> !Sync for Dma1<'a>

§

impl<'a> Unpin for Dma1<'a>

§

impl<'a> !UnwindSafe for Dma1<'a>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.