stm32/dma: add ChannelAndRequest helper.
This commit is contained in:
		
							parent
							
								
									d66c054aae
								
							
						
					
					
						commit
						02da66aec8
					
				@ -16,6 +16,9 @@ mod dmamux;
 | 
				
			|||||||
#[cfg(dmamux)]
 | 
					#[cfg(dmamux)]
 | 
				
			||||||
pub use dmamux::*;
 | 
					pub use dmamux::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mod util;
 | 
				
			||||||
 | 
					pub(crate) use util::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(crate) mod ringbuffer;
 | 
					pub(crate) mod ringbuffer;
 | 
				
			||||||
pub mod word;
 | 
					pub mod word;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										60
									
								
								embassy-stm32/src/dma/util.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								embassy-stm32/src/dma/util.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,60 @@
 | 
				
			|||||||
 | 
					use embassy_hal_internal::PeripheralRef;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use super::word::Word;
 | 
				
			||||||
 | 
					use super::{AnyChannel, Request, Transfer, TransferOptions};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Convenience wrapper, contains a channel and a request number.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// Commonly used in peripheral drivers that own DMA channels.
 | 
				
			||||||
 | 
					pub(crate) struct ChannelAndRequest<'d> {
 | 
				
			||||||
 | 
					    pub channel: PeripheralRef<'d, AnyChannel>,
 | 
				
			||||||
 | 
					    pub request: Request,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'d> ChannelAndRequest<'d> {
 | 
				
			||||||
 | 
					    pub unsafe fn read<'a, W: Word>(
 | 
				
			||||||
 | 
					        &'a mut self,
 | 
				
			||||||
 | 
					        peri_addr: *mut W,
 | 
				
			||||||
 | 
					        buf: &'a mut [W],
 | 
				
			||||||
 | 
					        options: TransferOptions,
 | 
				
			||||||
 | 
					    ) -> Transfer<'a> {
 | 
				
			||||||
 | 
					        Transfer::new_read(&mut self.channel, self.request, peri_addr, buf, options)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub unsafe fn read_raw<'a, W: Word>(
 | 
				
			||||||
 | 
					        &'a mut self,
 | 
				
			||||||
 | 
					        peri_addr: *mut W,
 | 
				
			||||||
 | 
					        buf: *mut [W],
 | 
				
			||||||
 | 
					        options: TransferOptions,
 | 
				
			||||||
 | 
					    ) -> Transfer<'a> {
 | 
				
			||||||
 | 
					        Transfer::new_read_raw(&mut self.channel, self.request, peri_addr, buf, options)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub unsafe fn write<'a, W: Word>(
 | 
				
			||||||
 | 
					        &'a mut self,
 | 
				
			||||||
 | 
					        buf: &'a [W],
 | 
				
			||||||
 | 
					        peri_addr: *mut W,
 | 
				
			||||||
 | 
					        options: TransferOptions,
 | 
				
			||||||
 | 
					    ) -> Transfer<'a> {
 | 
				
			||||||
 | 
					        Transfer::new_write(&mut self.channel, self.request, buf, peri_addr, options)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub unsafe fn write_raw<'a, W: Word>(
 | 
				
			||||||
 | 
					        &'a mut self,
 | 
				
			||||||
 | 
					        buf: *const [W],
 | 
				
			||||||
 | 
					        peri_addr: *mut W,
 | 
				
			||||||
 | 
					        options: TransferOptions,
 | 
				
			||||||
 | 
					    ) -> Transfer<'a> {
 | 
				
			||||||
 | 
					        Transfer::new_write_raw(&mut self.channel, self.request, buf, peri_addr, options)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub unsafe fn write_repeated<'a, W: Word>(
 | 
				
			||||||
 | 
					        &'a mut self,
 | 
				
			||||||
 | 
					        repeated: &'a W,
 | 
				
			||||||
 | 
					        count: usize,
 | 
				
			||||||
 | 
					        peri_addr: *mut W,
 | 
				
			||||||
 | 
					        options: TransferOptions,
 | 
				
			||||||
 | 
					    ) -> Transfer<'a> {
 | 
				
			||||||
 | 
					        Transfer::new_write_repeated(&mut self.channel, self.request, repeated, count, peri_addr, options)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -9,7 +9,7 @@ use embassy_futures::join::join;
 | 
				
			|||||||
use embassy_hal_internal::{into_ref, PeripheralRef};
 | 
					use embassy_hal_internal::{into_ref, PeripheralRef};
 | 
				
			||||||
pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
 | 
					pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::dma::{slice_ptr_parts, word, AnyChannel, Request, Transfer};
 | 
					use crate::dma::{slice_ptr_parts, word, ChannelAndRequest};
 | 
				
			||||||
use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed};
 | 
					use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed};
 | 
				
			||||||
use crate::mode::{Async, Blocking, Mode as PeriMode};
 | 
					use crate::mode::{Async, Blocking, Mode as PeriMode};
 | 
				
			||||||
use crate::pac::spi::{regs, vals, Spi as Regs};
 | 
					use crate::pac::spi::{regs, vals, Spi as Regs};
 | 
				
			||||||
@ -97,8 +97,8 @@ pub struct Spi<'d, T: Instance, M: PeriMode> {
 | 
				
			|||||||
    sck: Option<PeripheralRef<'d, AnyPin>>,
 | 
					    sck: Option<PeripheralRef<'d, AnyPin>>,
 | 
				
			||||||
    mosi: Option<PeripheralRef<'d, AnyPin>>,
 | 
					    mosi: Option<PeripheralRef<'d, AnyPin>>,
 | 
				
			||||||
    miso: Option<PeripheralRef<'d, AnyPin>>,
 | 
					    miso: Option<PeripheralRef<'d, AnyPin>>,
 | 
				
			||||||
    txdma: Option<(PeripheralRef<'d, AnyChannel>, Request)>,
 | 
					    txdma: Option<ChannelAndRequest<'d>>,
 | 
				
			||||||
    rxdma: Option<(PeripheralRef<'d, AnyChannel>, Request)>,
 | 
					    rxdma: Option<ChannelAndRequest<'d>>,
 | 
				
			||||||
    _phantom: PhantomData<M>,
 | 
					    _phantom: PhantomData<M>,
 | 
				
			||||||
    current_word_size: word_impl::Config,
 | 
					    current_word_size: word_impl::Config,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -109,8 +109,8 @@ impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> {
 | 
				
			|||||||
        sck: Option<PeripheralRef<'d, AnyPin>>,
 | 
					        sck: Option<PeripheralRef<'d, AnyPin>>,
 | 
				
			||||||
        mosi: Option<PeripheralRef<'d, AnyPin>>,
 | 
					        mosi: Option<PeripheralRef<'d, AnyPin>>,
 | 
				
			||||||
        miso: Option<PeripheralRef<'d, AnyPin>>,
 | 
					        miso: Option<PeripheralRef<'d, AnyPin>>,
 | 
				
			||||||
        txdma: Option<(PeripheralRef<'d, AnyChannel>, Request)>,
 | 
					        txdma: Option<ChannelAndRequest<'d>>,
 | 
				
			||||||
        rxdma: Option<(PeripheralRef<'d, AnyChannel>, Request)>,
 | 
					        rxdma: Option<ChannelAndRequest<'d>>,
 | 
				
			||||||
        config: Config,
 | 
					        config: Config,
 | 
				
			||||||
    ) -> Self {
 | 
					    ) -> Self {
 | 
				
			||||||
        into_ref!(peri);
 | 
					        into_ref!(peri);
 | 
				
			||||||
@ -593,9 +593,8 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
 | 
				
			|||||||
            w.set_spe(false);
 | 
					            w.set_spe(false);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let (txdma, tx_request) = self.txdma.as_mut().unwrap();
 | 
					 | 
				
			||||||
        let tx_dst = T::REGS.tx_ptr();
 | 
					        let tx_dst = T::REGS.tx_ptr();
 | 
				
			||||||
        let tx_f = unsafe { Transfer::new_write(txdma, *tx_request, data, tx_dst, Default::default()) };
 | 
					        let tx_f = unsafe { self.txdma.as_mut().unwrap().write(data, tx_dst, Default::default()) };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        set_txdmaen(T::REGS, true);
 | 
					        set_txdmaen(T::REGS, true);
 | 
				
			||||||
        T::REGS.cr1().modify(|w| {
 | 
					        T::REGS.cr1().modify(|w| {
 | 
				
			||||||
@ -632,22 +631,16 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        let clock_byte_count = data.len();
 | 
					        let clock_byte_count = data.len();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let (rxdma, rx_request) = self.rxdma.as_mut().unwrap();
 | 
					 | 
				
			||||||
        let rx_src = T::REGS.rx_ptr();
 | 
					        let rx_src = T::REGS.rx_ptr();
 | 
				
			||||||
        let rx_f = unsafe { Transfer::new_read(rxdma, *rx_request, rx_src, data, Default::default()) };
 | 
					        let rx_f = unsafe { self.rxdma.as_mut().unwrap().read(rx_src, data, Default::default()) };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let (txdma, tx_request) = self.txdma.as_mut().unwrap();
 | 
					 | 
				
			||||||
        let tx_dst = T::REGS.tx_ptr();
 | 
					        let tx_dst = T::REGS.tx_ptr();
 | 
				
			||||||
        let clock_byte = 0x00u8;
 | 
					        let clock_byte = 0x00u8;
 | 
				
			||||||
        let tx_f = unsafe {
 | 
					        let tx_f = unsafe {
 | 
				
			||||||
            Transfer::new_write_repeated(
 | 
					            self.txdma
 | 
				
			||||||
                txdma,
 | 
					                .as_mut()
 | 
				
			||||||
                *tx_request,
 | 
					                .unwrap()
 | 
				
			||||||
                &clock_byte,
 | 
					                .write_repeated(&clock_byte, clock_byte_count, tx_dst, Default::default())
 | 
				
			||||||
                clock_byte_count,
 | 
					 | 
				
			||||||
                tx_dst,
 | 
					 | 
				
			||||||
                Default::default(),
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        set_txdmaen(T::REGS, true);
 | 
					        set_txdmaen(T::REGS, true);
 | 
				
			||||||
@ -685,13 +678,16 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        set_rxdmaen(T::REGS, true);
 | 
					        set_rxdmaen(T::REGS, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let (rxdma, rx_request) = self.rxdma.as_mut().unwrap();
 | 
					 | 
				
			||||||
        let rx_src = T::REGS.rx_ptr();
 | 
					        let rx_src = T::REGS.rx_ptr();
 | 
				
			||||||
        let rx_f = unsafe { Transfer::new_read_raw(rxdma, *rx_request, rx_src, read, Default::default()) };
 | 
					        let rx_f = unsafe { self.rxdma.as_mut().unwrap().read_raw(rx_src, read, Default::default()) };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let (txdma, tx_request) = self.txdma.as_mut().unwrap();
 | 
					 | 
				
			||||||
        let tx_dst = T::REGS.tx_ptr();
 | 
					        let tx_dst = T::REGS.tx_ptr();
 | 
				
			||||||
        let tx_f = unsafe { Transfer::new_write_raw(txdma, *tx_request, write, tx_dst, Default::default()) };
 | 
					        let tx_f = unsafe {
 | 
				
			||||||
 | 
					            self.txdma
 | 
				
			||||||
 | 
					                .as_mut()
 | 
				
			||||||
 | 
					                .unwrap()
 | 
				
			||||||
 | 
					                .write_raw(write, tx_dst, Default::default())
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        set_txdmaen(T::REGS, true);
 | 
					        set_txdmaen(T::REGS, true);
 | 
				
			||||||
        T::REGS.cr1().modify(|w| {
 | 
					        T::REGS.cr1().modify(|w| {
 | 
				
			||||||
 | 
				
			|||||||
@ -73,8 +73,11 @@ macro_rules! dma_trait_impl {
 | 
				
			|||||||
macro_rules! new_dma {
 | 
					macro_rules! new_dma {
 | 
				
			||||||
    ($name:ident) => {{
 | 
					    ($name:ident) => {{
 | 
				
			||||||
        let dma = $name.into_ref();
 | 
					        let dma = $name.into_ref();
 | 
				
			||||||
        let req = dma.request();
 | 
					        let request = dma.request();
 | 
				
			||||||
        Some((dma.map_into(), req))
 | 
					        Some(crate::dma::ChannelAndRequest {
 | 
				
			||||||
 | 
					            channel: dma.map_into(),
 | 
				
			||||||
 | 
					            request,
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
    }};
 | 
					    }};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user