Skip to content

Commit 99cdd2f

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 24fdf8a commit 99cdd2f

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);
@@ -266,7 +270,12 @@ pub trait Channel: private::Channel {
266270
/// # Panics
267271
///
268272
/// Panics if this channel is enabled.
269-
fn set_peripheral_address(&mut self, address: u32, inc: Increment) {
273+
///
274+
/// # Safety
275+
///
276+
/// Callers must ensure the given address is the address of a peripheral
277+
/// register that supports DMA.
278+
unsafe fn set_peripheral_address(&mut self, address: u32, inc: Increment) {
270279
assert!(!self.is_enabled());
271280

272281
self.ch().par.write(|w| w.pa().bits(address));
@@ -281,7 +290,12 @@ pub trait Channel: private::Channel {
281290
/// # Panics
282291
///
283292
/// Panics if this channel is enabled.
284-
fn set_memory_address(&mut self, address: u32, inc: Increment) {
293+
///
294+
/// # Safety
295+
///
296+
/// Callers must ensure the given address is a valid memory address
297+
/// that will remain valid as long as at is used by DMA.
298+
unsafe fn set_memory_address(&mut self, address: u32, inc: Increment) {
285299
assert!(!self.is_enabled());
286300

287301
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
@@ -293,7 +293,8 @@ macro_rules! hal {
293293
{
294294
// NOTE(unsafe) taking the address of a register
295295
let pa = unsafe { &(*$USARTX::ptr()).rdr } as *const _ as u32;
296-
channel.set_peripheral_address(pa, dma::Increment::Disable);
296+
// NOTE(unsafe) usage of a valid peripheral address
297+
unsafe { channel.set_peripheral_address(pa, dma::Increment::Disable) };
297298

298299
dma::Transfer::start_write(buffer, channel, self)
299300
}
@@ -314,7 +315,8 @@ macro_rules! hal {
314315
{
315316
// NOTE(unsafe) taking the address of a register
316317
let pa = unsafe { &(*$USARTX::ptr()).tdr } as *const _ as u32;
317-
channel.set_peripheral_address(pa, dma::Increment::Disable);
318+
// NOTE(unsafe) usage of a valid peripheral address
319+
unsafe { channel.set_peripheral_address(pa, dma::Increment::Disable) };
318320

319321
dma::Transfer::start_read(buffer, channel, self)
320322
}

0 commit comments

Comments
 (0)