Skip to content

Commit

Permalink
Update docs on DMA code
Browse files Browse the repository at this point in the history
  • Loading branch information
thalesfragoso committed Oct 7, 2020
1 parent 7d2dfd0 commit f730774
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 84 deletions.
67 changes: 32 additions & 35 deletions src/adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -706,32 +706,30 @@ where
B: 'static,
{
fn circ_read(mut self, mut buffer: &'static mut [B; 2]) -> CircBuffer<B, Self> {
{
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
// until the end of the transfer.
let (ptr, len) = unsafe { buffer.static_write_buffer() };
self.channel
.set_peripheral_address(unsafe { &(*ADC1::ptr()).dr as *const _ as u32 }, false);
self.channel.set_memory_address(ptr as u32, true);
self.channel.set_transfer_length(len);

atomic::compiler_fence(Ordering::Release);

self.channel.ch().cr.modify(|_, w| {
w.mem2mem()
.clear_bit()
.pl()
.medium()
.msize()
.bits16()
.psize()
.bits16()
.circ()
.set_bit()
.dir()
.clear_bit()
});
}
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
// until the end of the transfer.
let (ptr, len) = unsafe { buffer.static_write_buffer() };
self.channel
.set_peripheral_address(unsafe { &(*ADC1::ptr()).dr as *const _ as u32 }, false);
self.channel.set_memory_address(ptr as u32, true);
self.channel.set_transfer_length(len);

atomic::compiler_fence(Ordering::Release);

self.channel.ch().cr.modify(|_, w| {
w.mem2mem()
.clear_bit()
.pl()
.medium()
.msize()
.bits16()
.psize()
.bits16()
.circ()
.set_bit()
.dir()
.clear_bit()
});

self.start();

Expand All @@ -745,15 +743,14 @@ where
B: StaticWriteBuffer<Word = u16>,
{
fn read(mut self, mut buffer: B) -> Transfer<W, B, Self> {
{
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
// until the end of the transfer.
let (ptr, len) = unsafe { buffer.static_write_buffer() };
self.channel
.set_peripheral_address(unsafe { &(*ADC1::ptr()).dr as *const _ as u32 }, false);
self.channel.set_memory_address(ptr as u32, true);
self.channel.set_transfer_length(len);
}
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
// until the end of the transfer.
let (ptr, len) = unsafe { buffer.static_write_buffer() };
self.channel
.set_peripheral_address(unsafe { &(*ADC1::ptr()).dr as *const _ as u32 }, false);
self.channel.set_memory_address(ptr as u32, true);
self.channel.set_transfer_length(len);

atomic::compiler_fence(Ordering::Release);
self.channel.ch().cr.modify(|_, w| {
w.mem2mem()
Expand Down
10 changes: 10 additions & 0 deletions src/dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,11 @@ macro_rules! dma {
// we need a fence here for the same reason we need one in `Transfer.wait`
atomic::compiler_fence(Ordering::Acquire);

// `Transfer` needs to have a `Drop` implementation, because we accept
// managed buffers that can free their memory on drop. Because of that
// we can't move out of the `Transfer`'s fields, so we use `ptr::read`
// and `mem::forget`.
//
// NOTE(unsafe) There is no panic branch between getting the resources
// and forgetting `self`.
unsafe {
Expand Down Expand Up @@ -350,6 +355,11 @@ macro_rules! dma {
// we need a fence here for the same reason we need one in `Transfer.wait`
atomic::compiler_fence(Ordering::Acquire);

// `Transfer` needs to have a `Drop` implementation, because we accept
// managed buffers that can free their memory on drop. Because of that
// we can't move out of the `Transfer`'s fields, so we use `ptr::read`
// and `mem::forget`.
//
// NOTE(unsafe) There is no panic branch between getting the resources
// and forgetting `self`.
unsafe {
Expand Down
69 changes: 31 additions & 38 deletions src/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,28 +590,24 @@ macro_rules! serialdma {
&'static mut [B; 2]: StaticWriteBuffer<Word = u8>,
B: 'static,
{
fn circ_read(mut self, mut buffer: &'static mut [B; 2],
) -> CircBuffer<B, Self>
{
{
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
// until the end of the transfer.
let (ptr, len) = unsafe { buffer.static_write_buffer() };
self.channel.set_peripheral_address(unsafe{ &(*$USARTX::ptr()).dr as *const _ as u32 }, false);
self.channel.set_memory_address(ptr as u32, true);
self.channel.set_transfer_length(len);

atomic::compiler_fence(Ordering::Release);

self.channel.ch().cr.modify(|_, w| { w
.mem2mem() .clear_bit()
.pl() .medium()
.msize() .bits8()
.psize() .bits8()
.circ() .set_bit()
.dir() .clear_bit()
});
}
fn circ_read(mut self, mut buffer: &'static mut [B; 2]) -> CircBuffer<B, Self> {
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
// until the end of the transfer.
let (ptr, len) = unsafe { buffer.static_write_buffer() };
self.channel.set_peripheral_address(unsafe{ &(*$USARTX::ptr()).dr as *const _ as u32 }, false);
self.channel.set_memory_address(ptr as u32, true);
self.channel.set_transfer_length(len);

atomic::compiler_fence(Ordering::Release);

self.channel.ch().cr.modify(|_, w| { w
.mem2mem() .clear_bit()
.pl() .medium()
.msize() .bits8()
.psize() .bits8()
.circ() .set_bit()
.dir() .clear_bit()
});

self.start();

Expand All @@ -624,14 +620,13 @@ macro_rules! serialdma {
B: StaticWriteBuffer<Word = u8>,
{
fn read(mut self, mut buffer: B) -> Transfer<W, B, Self> {
{
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
// until the end of the transfer.
let (ptr, len) = unsafe { buffer.static_write_buffer() };
self.channel.set_peripheral_address(unsafe{ &(*$USARTX::ptr()).dr as *const _ as u32 }, false);
self.channel.set_memory_address(ptr as u32, true);
self.channel.set_transfer_length(len);
}
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
// until the end of the transfer.
let (ptr, len) = unsafe { buffer.static_write_buffer() };
self.channel.set_peripheral_address(unsafe{ &(*$USARTX::ptr()).dr as *const _ as u32 }, false);
self.channel.set_memory_address(ptr as u32, true);
self.channel.set_transfer_length(len);

atomic::compiler_fence(Ordering::Release);
self.channel.ch().cr.modify(|_, w| { w
.mem2mem() .clear_bit()
Expand All @@ -652,16 +647,14 @@ macro_rules! serialdma {
B: StaticReadBuffer<Word = u8>,
{
fn write(mut self, buffer: B) -> Transfer<R, B, Self> {
{
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
// until the end of the transfer.
let (ptr, len) = unsafe { buffer.static_read_buffer() };
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
// until the end of the transfer.
let (ptr, len) = unsafe { buffer.static_read_buffer() };

self.channel.set_peripheral_address(unsafe{ &(*$USARTX::ptr()).dr as *const _ as u32 }, false);
self.channel.set_peripheral_address(unsafe{ &(*$USARTX::ptr()).dr as *const _ as u32 }, false);

self.channel.set_memory_address(ptr as u32, true);
self.channel.set_transfer_length(len);
}
self.channel.set_memory_address(ptr as u32, true);
self.channel.set_transfer_length(len);

atomic::compiler_fence(Ordering::Release);

Expand Down
21 changes: 10 additions & 11 deletions src/spi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,17 +542,16 @@ macro_rules! spi_dma {
B: StaticReadBuffer<Word = u8>,
{
fn write(mut self, buffer: B) -> Transfer<R, B, Self> {
{
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
// until the end of the transfer.
let (ptr, len) = unsafe { buffer.static_read_buffer() };
self.channel.set_peripheral_address(
unsafe { &(*$SPIi::ptr()).dr as *const _ as u32 },
false,
);
self.channel.set_memory_address(ptr as u32, true);
self.channel.set_transfer_length(len);
}
// NOTE(unsafe) We own the buffer now and we won't call other `&mut` on it
// until the end of the transfer.
let (ptr, len) = unsafe { buffer.static_read_buffer() };
self.channel.set_peripheral_address(
unsafe { &(*$SPIi::ptr()).dr as *const _ as u32 },
false,
);
self.channel.set_memory_address(ptr as u32, true);
self.channel.set_transfer_length(len);

atomic::compiler_fence(Ordering::Release);
self.channel.ch().cr.modify(|_, w| {
w
Expand Down

0 comments on commit f730774

Please sign in to comment.