diff --git a/embassy-rp/src/dma.rs b/embassy-rp/src/dma.rs index 75ad640c..25e3ec8f 100644 --- a/embassy-rp/src/dma.rs +++ b/embassy-rp/src/dma.rs @@ -15,27 +15,47 @@ use crate::{interrupt, pac, peripherals}; unsafe fn DMA_IRQ_0() { let ints0 = pac::DMA.ints0().read().ints0(); - critical_section::with(|_| { - for channel in 0..CHANNEL_COUNT { - if ints0 & (1 << channel) == (1 << channel) { - CHANNEL_WAKERS[channel].wake(); - } + for channel in 0..CHANNEL_COUNT { + if ints0 & (1 << channel) == (1 << channel) { + CHANNEL_WAKERS[channel].wake(); } - pac::DMA.ints0().write(|w| w.set_ints0(ints0)); - }); + } + pac::DMA.ints0().write(|w| w.set_ints0(ints0)); } -pub fn read<'a, C: Channel, W: Word>(ch: impl Peripheral
+ 'a, from: *const W, to: &mut [W]) -> Transfer<'a, C> { +pub(crate) unsafe fn init() { + let irq = interrupt::DMA_IRQ_0::steal(); + irq.disable(); + irq.set_priority(interrupt::Priority::P6); + + pac::DMA.inte0().write(|w| w.set_inte0(0xFFFF)); + + irq.enable(); +} + +pub unsafe fn read<'a, C: Channel, W: Word>( + ch: impl Peripheral
+ 'a, + from: *const W, + to: &mut [W], +) -> Transfer<'a, C> { let (ptr, len) = crate::dma::slice_ptr_parts_mut(to); copy_inner(ch, from as *const u32, ptr as *mut u32, len, W::size(), false, true) } -pub fn write<'a, C: Channel, W: Word>(ch: impl Peripheral
+ 'a, from: &[W], to: *mut W) -> Transfer<'a, C> { +pub unsafe fn write<'a, C: Channel, W: Word>( + ch: impl Peripheral
+ 'a, + from: &[W], + to: *mut W, +) -> Transfer<'a, C> { let (from_ptr, len) = crate::dma::slice_ptr_parts(from); copy_inner(ch, from_ptr as *const u32, to as *mut u32, len, W::size(), true, false) } -pub fn copy<'a, C: Channel, W: Word>(ch: impl Peripheral
+ 'a, from: &[W], to: &mut [W]) -> Transfer<'a, C> { +pub unsafe fn copy<'a, C: Channel, W: Word>( + ch: impl Peripheral
+ 'a, + from: &[W], + to: &mut [W], +) -> Transfer<'a, C> { let (from_ptr, from_len) = crate::dma::slice_ptr_parts(from); let (to_ptr, to_len) = crate::dma::slice_ptr_parts_mut(to); assert_eq!(from_len, to_len); @@ -91,16 +111,6 @@ impl<'a, C: Channel> Transfer<'a, C> { pub(crate) fn new(channel: impl Peripheral
+ 'a) -> Self { into_ref!(channel); - unsafe { - let irq = interrupt::DMA_IRQ_0::steal(); - irq.disable(); - irq.set_priority(interrupt::Priority::P6); - - pac::DMA.inte0().write(|w| w.set_inte0(1 << channel.number())); - - irq.enable(); - } - Self { channel } } } diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs index 8c053a4f..6db77b8c 100644 --- a/embassy-rp/src/lib.rs +++ b/embassy-rp/src/lib.rs @@ -105,6 +105,7 @@ pub fn init(_config: config::Config) -> Peripherals { unsafe { clocks::init(); timer::init(); + dma::init(); } peripherals diff --git a/embassy-rp/src/uart.rs b/embassy-rp/src/uart.rs index 03623a9f..9d94dcf2 100644 --- a/embassy-rp/src/uart.rs +++ b/embassy-rp/src/uart.rs @@ -120,17 +120,16 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { impl<'d, T: Instance> UartTx<'d, T, Async> { pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { - if let Some(ch) = &mut self.tx_dma { - unsafe { - T::regs().uartdmacr().modify(|reg| { - reg.set_txdmae(true); - }); - } + let ch = self.tx_dma.as_mut().unwrap(); + let transfer = unsafe { + T::regs().uartdmacr().modify(|reg| { + reg.set_txdmae(true); + }); // If we don't assign future to a variable, the data register pointer // is held across an await and makes the future non-Send. - let transfer = crate::dma::write(ch, buffer, T::regs().uartdr().ptr() as *mut _); - transfer.await; - } + crate::dma::write(ch, buffer, T::regs().uartdr().ptr() as *mut _) + }; + transfer.await; Ok(()) } } @@ -170,17 +169,16 @@ impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> { impl<'d, T: Instance> UartRx<'d, T, Async> { pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { - if let Some(ch) = &mut self.rx_dma { - unsafe { - T::regs().uartdmacr().modify(|reg| { - reg.set_rxdmae(true); - }); - } + let ch = self.rx_dma.as_mut().unwrap(); + let transfer = unsafe { + T::regs().uartdmacr().modify(|reg| { + reg.set_rxdmae(true); + }); // If we don't assign future to a variable, the data register pointer // is held across an await and makes the future non-Send. - let transfer = crate::dma::read(ch, T::regs().uartdr().ptr() as *const _, buffer); - transfer.await; - } + crate::dma::read(ch, T::regs().uartdr().ptr() as *const _, buffer) + }; + transfer.await; Ok(()) } }