diff --git a/src/dma.rs b/src/dma.rs index cd6467b74..9ae9965d7 100644 --- a/src/dma.rs +++ b/src/dma.rs @@ -59,7 +59,9 @@ impl Transfer { let (ptr, len) = unsafe { buffer.write_buffer() }; let len = u16(len).expect("buffer is too large"); - channel.set_memory_address(ptr as u32, Increment::Enable); + // NOTE(unsafe) We are using the address of a 'static WriteBuffer here, + // which is guaranteed to be safe for DMA. + unsafe { channel.set_memory_address(ptr as u32, Increment::Enable) }; channel.set_transfer_length(len); channel.set_word_size::(); channel.set_direction(Direction::FromPeripheral); @@ -84,7 +86,9 @@ impl Transfer { let (ptr, len) = unsafe { buffer.read_buffer() }; let len = u16(len).expect("buffer is too large"); - channel.set_memory_address(ptr as u32, Increment::Enable); + // NOTE(unsafe) We are using the address of a 'static ReadBuffer here, + // which is guaranteed to be safe for DMA. + unsafe { channel.set_memory_address(ptr as u32, Increment::Enable) }; channel.set_transfer_length(len); channel.set_word_size::(); channel.set_direction(Direction::FromMemory); @@ -477,7 +481,12 @@ pub trait Channel: private::Channel { /// # Panics /// /// Panics if this channel is enabled. - fn set_peripheral_address(&mut self, address: u32, inc: Increment) { + /// + /// # Safety + /// + /// Callers must ensure the given address is the address of a peripheral + /// register that supports DMA. + unsafe fn set_peripheral_address(&mut self, address: u32, inc: Increment) { assert!(!self.is_enabled()); self.ch().par.write(|w| w.pa().bits(address)); @@ -492,7 +501,12 @@ pub trait Channel: private::Channel { /// # Panics /// /// Panics if this channel is enabled. - fn set_memory_address(&mut self, address: u32, inc: Increment) { + /// + /// # Safety + /// + /// Callers must ensure the given address is a valid memory address + /// that will remain valid as long as at is used by DMA. + unsafe fn set_memory_address(&mut self, address: u32, inc: Increment) { assert!(!self.is_enabled()); self.ch().mar.write(|w| w.ma().bits(address)); diff --git a/src/serial.rs b/src/serial.rs index 6f2599c70..74d01964d 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -265,7 +265,8 @@ macro_rules! hal { { // NOTE(unsafe) taking the address of a register let pa = unsafe { &(*$USARTX::ptr()).rdr } as *const _ as u32; - channel.set_peripheral_address(pa, dma::Increment::Disable); + // NOTE(unsafe) usage of a valid peripheral address + unsafe { channel.set_peripheral_address(pa, dma::Increment::Disable) }; dma::Transfer::start_write(buffer, channel, self) } @@ -286,7 +287,8 @@ macro_rules! hal { { // NOTE(unsafe) taking the address of a register let pa = unsafe { &(*$USARTX::ptr()).tdr } as *const _ as u32; - channel.set_peripheral_address(pa, dma::Increment::Disable); + // NOTE(unsafe) usage of a valid peripheral address + unsafe { channel.set_peripheral_address(pa, dma::Increment::Disable) }; dma::Transfer::start_read(buffer, channel, self) }