Skip to content

Commit

Permalink
Add channel read write trait marker
Browse files Browse the repository at this point in the history
  • Loading branch information
Sh3Rm4n committed Jan 6, 2024
1 parent a9f8726 commit db99132
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 11 deletions.
3 changes: 2 additions & 1 deletion examples/serial_dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,15 @@ fn main() -> ! {
// the buffer we are going to receive the transmitted data in
let rx_buf = singleton!(: [u8; 9] = [0; 9]).unwrap();

// TODO: where to find this information and bind this information to serial implementation
// DMA channel selection depends on the peripheral:
// - USART1: TX = 4, RX = 5
// - USART2: TX = 6, RX = 7
// - USART3: TX = 3, RX = 2
let (tx_channel, rx_channel) = (dma1.ch4, dma1.ch5);

// start separate DMAs for sending and receiving the data
let transfer = serial.transfer_exact(rx_buf, rx_channel, tx_buf, tx_channel);
let transfer = serial.transfer_exact(rx_buf, tx_channel, tx_buf, rx_channel);

// block until all data was transmitted and received
let ((rx_buf, tx_buf), (rx_channel, tx_channel)) = transfer.wait();
Expand Down
17 changes: 13 additions & 4 deletions src/dma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,16 +180,16 @@ impl<'t, B, C: Channel, T: Target> Transfer<'t, B, C, T> {

impl<'t, BR, BW, CR, CW, T> Transfer<'t, (BR, BW), (CR, CW), T>
where
CR: Channel,
CW: Channel,
CR: Channel, /* + ReceiveChannel */
CW: Channel, /* + TransmitChannel */
T: Target,
{
/// Start a DMA write transfer.
///
/// # Panics
///
/// Panics if the buffer is longer than 65535 words.
// TODO: sort arguments (target at first)
// TODO: sort arguments (target at first, write at first (see embedded hal?))
pub fn start_transfer(
buffer_read: BR,
mut buffer_write: BW,
Expand All @@ -203,7 +203,7 @@ where
T: OnChannel<CR> + OnChannel<CW>,
{
// TODO: ensure same buffer length
// TODO: ensure same word type
// TODO: ensure same nord type

// SAFETY: We don't know the concrete type of `buffer` here, all
// we can use are its `WriteBuffer` methods. Hence the only `&mut self`
Expand Down Expand Up @@ -714,6 +714,10 @@ dma!( 2: { 1,2,3,4,5 } );

/// Marker trait mapping DMA targets to their channels
pub trait OnChannel<C: Channel>: Target + crate::private::Sealed {}
// TODO: put this in serial mod
// TODO: the naming is switched
pub trait TransmitChannel: crate::private::Sealed {}
pub trait ReceiveChannel: crate::private::Sealed {}

macro_rules! on_channel {
(
Expand All @@ -726,6 +730,11 @@ macro_rules! on_channel {
impl<Tx, Rx> crate::private::Sealed for serial::Serial<$USART, (Tx, Rx)> {}
impl<Tx, Rx> OnChannel<$dma::$TxChannel> for serial::Serial<$USART, (Tx, Rx)> {}
impl<Tx, Rx> OnChannel<$dma::$RxChannel> for serial::Serial<$USART, (Tx, Rx)> {}

impl crate::private::Sealed for $dma::$TxChannel {}
impl TransmitChannel for $dma::$TxChannel {}
impl crate::private::Sealed for $dma::$RxChannel {}
impl ReceiveChannel for $dma::$RxChannel {}
)+
)+
};
Expand Down
12 changes: 6 additions & 6 deletions src/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -865,7 +865,7 @@ where
where
Self: dma::OnChannel<C>,
B: dma::WriteBuffer<Word = u8> + 'static,
C: dma::Channel,
C: dma::Channel + dma::ReceiveChannel,
{
// SAFETY: RDR is valid peripheral address, safe to dereference and pass to the DMA
unsafe {
Expand All @@ -883,7 +883,7 @@ where
where
Self: dma::OnChannel<C>,
B: dma::ReadBuffer<Word = u8> + 'static,
C: dma::Channel,
C: dma::Channel + dma::TransmitChannel,
{
// SAFETY: TDR is valid peripheral address, safe to dereference and pass to the DMA
unsafe {
Expand All @@ -906,21 +906,21 @@ where
where
Self: dma::OnChannel<CR> + dma::OnChannel<CW>,
BR: dma::ReadBuffer<Word = u8> + 'static,
CR: dma::Channel,
CR: dma::Channel + dma::TransmitChannel,
BW: dma::WriteBuffer<Word = u8> + 'static,
CW: dma::Channel,
CW: dma::Channel + dma::ReceiveChannel,
{
// SAFETY: TDR is valid peripheral address, safe to dereference and pass to the DMA
unsafe {
channel_write.set_peripheral_address(
channel_read.set_peripheral_address(
core::ptr::addr_of!(self.usart.tdr) as u32,
dma::Increment::Disable,
);
};

// SAFETY: RDR is valid peripheral address, safe to dereference and pass to the DMA
unsafe {
channel_read.set_peripheral_address(
channel_write.set_peripheral_address(
core::ptr::addr_of!(self.usart.rdr) as u32,
dma::Increment::Disable,
);
Expand Down

0 comments on commit db99132

Please sign in to comment.