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:
- Keep Stream<DmaX>
- Change to Stream<DmaXPeripheral>
- 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.