Skip to content

Commit

Permalink
Add an example for serial communication using DMA
Browse files Browse the repository at this point in the history
  • Loading branch information
teskje committed Apr 5, 2020
1 parent 3ac50a3 commit 91467af
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,7 @@ required-features = ["rt", "stm32f303xc", "stm32-usbd"]
[[example]]
name = "spi"
required-features = ["stm32f303"]

[[example]]
name = "serial_dma"
required-features = ["stm32f303"]
69 changes: 69 additions & 0 deletions examples/serial_dma.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//! Example of transmitting data over serial interface using DMA.
//! For this to work, the PA9 and PA10 pins must be connected.
//! Target board: STM32F3DISCOVERY
#![no_std]
#![no_main]

use panic_semihosting as _;

use core::pin::Pin;
use cortex_m::{asm, singleton};
use cortex_m_rt::entry;
use stm32f3xx_hal::{prelude::*, serial::Serial, stm32};

#[entry]
fn main() -> ! {
let dp = stm32::Peripherals::take().unwrap();

let mut flash = dp.FLASH.constrain();
let mut rcc = dp.RCC.constrain();
let clocks = rcc.cfgr.freeze(&mut flash.acr);

let mut gpioa = dp.GPIOA.split(&mut rcc.ahb);

let pins = (
gpioa.pa9.into_af7(&mut gpioa.moder, &mut gpioa.afrh),
gpioa.pa10.into_af7(&mut gpioa.moder, &mut gpioa.afrh),
);
let serial = Serial::usart1(dp.USART1, pins, 9600.bps(), clocks, &mut rcc.apb2);
let (tx, rx) = serial.split();

let dma1 = dp.DMA1.split(&mut rcc.ahb);

// the data we are going to send over serial
let tx_buf = singleton!(: [u8; 9] = *b"hello DMA").unwrap();
// the buffer we are going to receive the transmitted data in
let rx_buf = singleton!(: [u8; 9] = [0; 9]).unwrap();

// 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 sending = tx.write_all(Pin::new(tx_buf), tx_channel);
let receiving = rx.read_all(Pin::new(rx_buf), rx_channel);

// block until all data was transmitted and received
let (mut tx_buf, tx_channel, tx) = sending.wait();
let (rx_buf, rx_channel, rx) = receiving.wait();

assert_eq!(tx_buf, rx_buf);

// After a transfer is finished its parts can be re-used for another one.
tx_buf.copy_from_slice(b"hi again!");

let sending = tx.write_all(tx_buf, tx_channel);
let receiving = rx.read_all(rx_buf, rx_channel);

let (tx_buf, ..) = sending.wait();
let (rx_buf, ..) = receiving.wait();

assert_eq!(tx_buf, rx_buf);

loop {
continue;
}
}

0 comments on commit 91467af

Please sign in to comment.