Skip to content

Commit 7190b1a

Browse files
committed
Adjust to the new unsafe DMA register access methods
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.
1 parent 47dd869 commit 7190b1a

File tree

2 files changed

+22
-6
lines changed

2 files changed

+22
-6
lines changed

src/dma.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ impl<B, C: Channel, T: Target> Transfer<B, C, T> {
5959
let (ptr, len) = unsafe { buffer.write_buffer() };
6060
let len = u16(len).expect("buffer is too large");
6161

62-
channel.set_memory_address(ptr as u32, Increment::Enable);
62+
// NOTE(unsafe) We are using the address of a 'static WriteBuffer here,
63+
// which is guaranteed to be safe for DMA.
64+
unsafe { channel.set_memory_address(ptr as u32, Increment::Enable) };
6365
channel.set_transfer_length(len);
6466
channel.set_word_size::<B::Word>();
6567
channel.set_direction(Direction::FromPeripheral);
@@ -84,7 +86,9 @@ impl<B, C: Channel, T: Target> Transfer<B, C, T> {
8486
let (ptr, len) = unsafe { buffer.read_buffer() };
8587
let len = u16(len).expect("buffer is too large");
8688

87-
channel.set_memory_address(ptr as u32, Increment::Enable);
89+
// NOTE(unsafe) We are using the address of a 'static ReadBuffer here,
90+
// which is guaranteed to be safe for DMA.
91+
unsafe { channel.set_memory_address(ptr as u32, Increment::Enable) };
8892
channel.set_transfer_length(len);
8993
channel.set_word_size::<B::Word>();
9094
channel.set_direction(Direction::FromMemory);
@@ -477,7 +481,12 @@ pub trait Channel: private::Channel {
477481
/// # Panics
478482
///
479483
/// Panics if this channel is enabled.
480-
fn set_peripheral_address(&mut self, address: u32, inc: Increment) {
484+
///
485+
/// # Safety
486+
///
487+
/// Callers must ensure the given address is the address of a peripheral
488+
/// register that supports DMA.
489+
unsafe fn set_peripheral_address(&mut self, address: u32, inc: Increment) {
481490
assert!(!self.is_enabled());
482491

483492
self.ch().par.write(|w| w.pa().bits(address));
@@ -492,7 +501,12 @@ pub trait Channel: private::Channel {
492501
/// # Panics
493502
///
494503
/// Panics if this channel is enabled.
495-
fn set_memory_address(&mut self, address: u32, inc: Increment) {
504+
///
505+
/// # Safety
506+
///
507+
/// Callers must ensure the given address is a valid memory address
508+
/// that will remain valid as long as at is used by DMA.
509+
unsafe fn set_memory_address(&mut self, address: u32, inc: Increment) {
496510
assert!(!self.is_enabled());
497511

498512
self.ch().mar.write(|w| w.ma().bits(address));

src/serial.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,8 @@ macro_rules! hal {
265265
{
266266
// NOTE(unsafe) taking the address of a register
267267
let pa = unsafe { &(*$USARTX::ptr()).rdr } as *const _ as u32;
268-
channel.set_peripheral_address(pa, dma::Increment::Disable);
268+
// NOTE(unsafe) usage of a valid peripheral address
269+
unsafe { channel.set_peripheral_address(pa, dma::Increment::Disable) };
269270

270271
dma::Transfer::start_write(buffer, channel, self)
271272
}
@@ -286,7 +287,8 @@ macro_rules! hal {
286287
{
287288
// NOTE(unsafe) taking the address of a register
288289
let pa = unsafe { &(*$USARTX::ptr()).tdr } as *const _ as u32;
289-
channel.set_peripheral_address(pa, dma::Increment::Disable);
290+
// NOTE(unsafe) usage of a valid peripheral address
291+
unsafe { channel.set_peripheral_address(pa, dma::Increment::Disable) };
290292

291293
dma::Transfer::start_read(buffer, channel, self)
292294
}

0 commit comments

Comments
 (0)