Skip to content

Commit

Permalink
Merge pull request #603 from Gip-Gip/byteswapping-config
Browse files Browse the repository at this point in the history
Byteswapping config
  • Loading branch information
ithinuel authored May 9, 2023
2 parents b8d9124 + 5ae4852 commit 6e9762a
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 12 deletions.
35 changes: 29 additions & 6 deletions rp2040-hal/src/dma/bidirectional.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ where
to: TO,
from_pace: Pace,
to_pace: Pace,
bswap: bool,
}

impl<CH1, CH2, FROM, BIDI, TO, WORD> Config<CH1, CH2, FROM, BIDI, TO>
Expand All @@ -39,6 +40,7 @@ where
from,
bidi,
to,
bswap: false,
from_pace: Pace::PreferSink,
to_pace: Pace::PreferSink,
}
Expand All @@ -56,18 +58,39 @@ where
self.to_pace = pace;
}

/// Enable/disable byteswapping for the DMA transfers, default value is false.
///
/// For byte data, this has no effect. For halfword data, the two bytes of
/// each halfword are swapped. For word data, the four bytes of each word
/// are swapped to reverse order.
///
/// This is a convenient way to change the (half-)words' byte endianness on the fly.
pub fn bswap(&mut self, bswap: bool) {
self.bswap = bswap;
}

/// Start the DMA transfer
pub fn start(mut self) -> Transfer<CH1, CH2, FROM, BIDI, TO> {
cortex_m::asm::dsb();
compiler_fence(Ordering::SeqCst);

// Configure the DMA channel and start it.
self.ch
.0
.config(&self.from, &mut self.bidi, self.from_pace, None, false);
self.ch
.1
.config(&self.bidi, &mut self.to, self.to_pace, None, false);
self.ch.0.config(
&self.from,
&mut self.bidi,
self.from_pace,
self.bswap,
None,
false,
);
self.ch.1.config(
&self.bidi,
&mut self.to,
self.to_pace,
self.bswap,
None,
false,
);
self.ch.0.start_both(&mut self.ch.1);

Transfer {
Expand Down
33 changes: 28 additions & 5 deletions rp2040-hal/src/dma/double_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub struct Config<CH1: SingleChannel, CH2: SingleChannel, FROM: ReadTarget, TO:
ch: (CH1, CH2),
from: FROM,
to: TO,
bswap: bool,
pace: Pace,
}

Expand All @@ -28,6 +29,7 @@ where
ch,
from,
to,
bswap: false,
pace: Pace::PreferSource,
}
}
Expand All @@ -41,6 +43,17 @@ where
self.pace = pace;
}

/// Enable/disable byteswapping for the DMA transfers, default value is false.
///
/// For byte data, this has no effect. For halfword data, the two bytes of
/// each halfword are swapped. For word data, the four bytes of each word
/// are swapped to reverse order.
///
/// This is a convenient way to change the (half-)words' byte endianness on the fly.
pub fn bswap(&mut self, bswap: bool) {
self.bswap = bswap;
}

/// Start the DMA transfer
pub fn start(mut self) -> Transfer<CH1, CH2, FROM, TO, ()> {
// TODO: Do we want to call any callbacks to configure source/sink?
Expand All @@ -53,13 +66,14 @@ where
// Configure the DMA channel and start it.
self.ch
.0
.config(&self.from, &mut self.to, self.pace, None, true);
.config(&self.from, &mut self.to, self.pace, self.bswap, None, true);

Transfer {
ch: self.ch,
from: self.from,
to: self.to,
pace: self.pace,
bswap: self.bswap,
state: (),
second_ch: false,
}
Expand All @@ -83,6 +97,7 @@ where
from: FROM,
to: TO,
pace: Pace,
bswap: bool,
state: STATE,
second_ch: bool,
}
Expand Down Expand Up @@ -161,9 +176,13 @@ where

// Configure the _other_ DMA channel, but do not start it yet.
if self.second_ch {
self.ch.0.config(&buf, &mut self.to, self.pace, None, false);
self.ch
.0
.config(&buf, &mut self.to, self.pace, self.bswap, None, false);
} else {
self.ch.1.config(&buf, &mut self.to, self.pace, None, false);
self.ch
.1
.config(&buf, &mut self.to, self.pace, self.bswap, None, false);
}

// Chain the first channel to the second.
Expand All @@ -178,6 +197,7 @@ where
from: self.from,
to: self.to,
pace: self.pace,
bswap: self.bswap,
state: ReadNext(buf),
second_ch: self.second_ch,
}
Expand Down Expand Up @@ -205,11 +225,11 @@ where
if self.second_ch {
self.ch
.0
.config(&self.from, &mut buf, self.pace, None, false);
.config(&self.from, &mut buf, self.pace, self.bswap, None, false);
} else {
self.ch
.1
.config(&self.from, &mut buf, self.pace, None, false);
.config(&self.from, &mut buf, self.pace, self.bswap, None, false);
}

// Chain the first channel to the second.
Expand All @@ -224,6 +244,7 @@ where
from: self.from,
to: self.to,
pace: self.pace,
bswap: self.bswap,
state: WriteNext(buf),
second_ch: self.second_ch,
}
Expand Down Expand Up @@ -254,6 +275,7 @@ where
from: self.state.0,
to: self.to,
pace: self.pace,
bswap: self.bswap,
state: (),
second_ch: !self.second_ch,
},
Expand Down Expand Up @@ -285,6 +307,7 @@ where
from: self.from,
to: self.state.0,
pace: self.pace,
bswap: self.bswap,
state: (),
second_ch: !self.second_ch,
},
Expand Down
15 changes: 14 additions & 1 deletion rp2040-hal/src/dma/single_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub struct Config<CH: SingleChannel, FROM: ReadTarget, TO: WriteTarget> {
from: FROM,
to: TO,
pace: Pace,
bswap: bool,
}

impl<CH, FROM, TO, WORD> Config<CH, FROM, TO>
Expand All @@ -27,6 +28,7 @@ where
from,
to,
pace: Pace::PreferSource,
bswap: false,
}
}

Expand All @@ -39,6 +41,17 @@ where
self.pace = pace;
}

/// Enable/disable byteswapping for the DMA transfers, default value is false.
///
/// For byte data, this has no effect. For halfword data, the two bytes of
/// each halfword are swapped. For word data, the four bytes of each word
/// are swapped to reverse order.
///
/// This is a convenient way to change the (half-)words' byte endianness on the fly.
pub fn bswap(&mut self, bswap: bool) {
self.bswap = bswap;
}

/// Start the DMA transfer
pub fn start(mut self) -> Transfer<CH, FROM, TO> {
// TODO: Do we want to call any callbacks to configure source/sink?
Expand All @@ -50,7 +63,7 @@ where

// Configure the DMA channel and start it.
self.ch
.config(&self.from, &mut self.to, self.pace, None, true);
.config(&self.from, &mut self.to, self.pace, self.bswap, None, true);

Transfer {
ch: self.ch,
Expand Down
3 changes: 3 additions & 0 deletions rp2040-hal/src/dma/single_channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ pub(crate) trait ChannelConfig {
from: &FROM,
to: &mut TO,
pace: Pace,
bswap: bool,
chain_to: Option<u8>,
start: bool,
) where
Expand Down Expand Up @@ -156,6 +157,7 @@ impl<CH: SingleChannel> ChannelConfig for CH {
from: &FROM,
to: &mut TO,
pace: Pace,
bswap: bool,
chain_to: Option<u8>,
start: bool,
) where
Expand All @@ -180,6 +182,7 @@ impl<CH: SingleChannel> ChannelConfig for CH {
w.incr_read().bit(src_incr);
w.incr_write().bit(dest_incr);
w.treq_sel().bits(treq);
w.bswap().bit(bswap);
w.chain_to().bits(chain_to.unwrap_or_else(|| self.id()));
w.en().bit(true);
w
Expand Down

0 comments on commit 6e9762a

Please sign in to comment.