Skip to content

Commit

Permalink
Adjust to the new unsafe DMA register access methods
Browse files Browse the repository at this point in the history
Setting the memory and peripheral addresses of a DMA channel has been
marked unsafe in the newest version of the stm32f3 HAL. This commit
adjusts the DMA abstraction code accordingly.
  • Loading branch information
teskje committed Aug 7, 2020
1 parent bd6debf commit d55c2e4
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 6 deletions.
22 changes: 18 additions & 4 deletions src/dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ impl<B, C: Channel, T: Target> Transfer<B, C, T> {
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::<B::Word>();
channel.set_direction(Direction::FromPeripheral);
Expand All @@ -84,7 +86,9 @@ impl<B, C: Channel, T: Target> Transfer<B, C, T> {
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::<B::Word>();
channel.set_direction(Direction::FromMemory);
Expand Down Expand Up @@ -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));
Expand All @@ -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));
Expand Down
6 changes: 4 additions & 2 deletions src/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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)
}
Expand Down

0 comments on commit d55c2e4

Please sign in to comment.