From e237b8034452d1c77f108614f55ae0c46439e4f9 Mon Sep 17 00:00:00 2001 From: Richard Meadows <962920+richardeoin@users.noreply.github.com> Date: Sun, 18 Oct 2020 23:22:20 +0200 Subject: [PATCH] Experiment with implementing TargetAddress on a HAL structure As well as the PAC structure. Also add the option to include an extra layer of indirection for the target register --- src/dma/bdma.rs | 5 ++++ src/dma/macros.rs | 58 +++++++++++++++++++++++++++++++++++++++-------- src/i2c.rs | 5 ++++ 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/dma/bdma.rs b/src/dma/bdma.rs index 074e50633..405ded518 100644 --- a/src/dma/bdma.rs +++ b/src/dma/bdma.rs @@ -10,6 +10,7 @@ use super::{ use core::marker::PhantomData; use crate::{ + i2c::I2c, pac::{self, BDMA, DMAMUX2}, rcc::{rec, rec::ResetEnable}, //serial::{Rx, Tx}, @@ -478,4 +479,8 @@ peripheral_target_address!( (pac::SPI6, txdr, u8, M2P, DMAReq::SPI6_TX_DMA), (pac::I2C4, rxdr, u8, P2M, DMAReq::I2C4_RX_DMA), (pac::I2C4, txdr, u8, M2P, DMAReq::I2C4_TX_DMA), + (INNER, I2c, rxdr, u8, P2M, DMAReq::I2C4_RX_DMA), + (INNER, I2c, txdr, u8, M2P, DMAReq::I2C4_TX_DMA), +); + ); diff --git a/src/dma/macros.rs b/src/dma/macros.rs index 0ebf1d757..dd4a8a8c5 100644 --- a/src/dma/macros.rs +++ b/src/dma/macros.rs @@ -3,24 +3,62 @@ // Convenience macro for implementing target addresses on peripherals macro_rules! peripheral_target_address { ($( - ($peripheral:ty, $register:ident $(($TRBUFF:ident))*, $size:ty, - $dir:ty $(, $mux:expr)*) + $peripheral:tt ),+ $(,)*) => { $( - unsafe impl TargetAddress<$dir> for &mut $peripheral { - #[inline(always)] - fn address(&self) -> u32 { - &self.$register as *const _ as u32 - } + peripheral_target_instance!($peripheral); + )+ + }; +} +macro_rules! peripheral_target_instance { + (($peripheral:ty, $register:ident $(($TRBUFF:ident))*, $size:ty, + $dir:ty $(, $mux:expr)*)) => { + unsafe impl TargetAddress<$dir> for &mut $peripheral { + #[inline(always)] + fn address(&self) -> u32 { + &self.$register as *const _ as u32 + } - type MemSize = $size; + type MemSize = $size; + $( + const REQUEST_LINE: Option = Some($mux as u8); + )* $( - const REQUEST_LINE: Option = Some($mux as u8); + const $TRBUFF: bool = true; )* + } + }; + + ((INNER, $peripheral:ty, $register:ident $(($TRBUFF:ident))*, $size:ty, + $dir:ty $(, $mux:expr)*)) => { + unsafe impl TargetAddress<$dir> for &mut $peripheral { + #[inline(always)] + fn address(&self) -> u32 { + &self.inner().$register as *const _ as u32 + } + + type MemSize = $size; + $( + const REQUEST_LINE: Option = Some($mux as u8); + )* $( const $TRBUFF: bool = true; )* + } + }; + + (($peripheral:ty, $channel:ident.$register:ident, $size:ty, + $dir:ty $(, $mux:expr)*)) => { + unsafe impl TargetAddress<$dir> for &mut $peripheral { + #[inline(always)] + fn address(&self) -> u32 { + &self.$channel.$register as *const _ as u32 } - )+ + + type MemSize = $size; + $( + const REQUEST_LINE: Option = Some($mux as u8); + )* + } }; } diff --git a/src/i2c.rs b/src/i2c.rs index 8b303e006..2d8d207b1 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -313,6 +313,11 @@ macro_rules! i2c { I2c { i2c } } + /// Returns a reference to the inner peripheral + pub fn inner(&self) -> &$I2CX { + &self.i2c + } + /// Start listening for `event` pub fn listen(&mut self, event: Event) { self.i2c.cr1.modify(|_,w| {