Skip to content

Commit 91467af

Browse files
committed
Add an example for serial communication using DMA
1 parent 3ac50a3 commit 91467af

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,7 @@ required-features = ["rt", "stm32f303xc", "stm32-usbd"]
9393
[[example]]
9494
name = "spi"
9595
required-features = ["stm32f303"]
96+
97+
[[example]]
98+
name = "serial_dma"
99+
required-features = ["stm32f303"]

examples/serial_dma.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
//! Example of transmitting data over serial interface using DMA.
2+
//! For this to work, the PA9 and PA10 pins must be connected.
3+
//! Target board: STM32F3DISCOVERY
4+
5+
#![no_std]
6+
#![no_main]
7+
8+
use panic_semihosting as _;
9+
10+
use core::pin::Pin;
11+
use cortex_m::{asm, singleton};
12+
use cortex_m_rt::entry;
13+
use stm32f3xx_hal::{prelude::*, serial::Serial, stm32};
14+
15+
#[entry]
16+
fn main() -> ! {
17+
let dp = stm32::Peripherals::take().unwrap();
18+
19+
let mut flash = dp.FLASH.constrain();
20+
let mut rcc = dp.RCC.constrain();
21+
let clocks = rcc.cfgr.freeze(&mut flash.acr);
22+
23+
let mut gpioa = dp.GPIOA.split(&mut rcc.ahb);
24+
25+
let pins = (
26+
gpioa.pa9.into_af7(&mut gpioa.moder, &mut gpioa.afrh),
27+
gpioa.pa10.into_af7(&mut gpioa.moder, &mut gpioa.afrh),
28+
);
29+
let serial = Serial::usart1(dp.USART1, pins, 9600.bps(), clocks, &mut rcc.apb2);
30+
let (tx, rx) = serial.split();
31+
32+
let dma1 = dp.DMA1.split(&mut rcc.ahb);
33+
34+
// the data we are going to send over serial
35+
let tx_buf = singleton!(: [u8; 9] = *b"hello DMA").unwrap();
36+
// the buffer we are going to receive the transmitted data in
37+
let rx_buf = singleton!(: [u8; 9] = [0; 9]).unwrap();
38+
39+
// DMA channel selection depends on the peripheral:
40+
// - USART1: TX = 4, RX = 5
41+
// - USART2: TX = 6, RX = 7
42+
// - USART3: TX = 3, RX = 2
43+
let (tx_channel, rx_channel) = (dma1.ch4, dma1.ch5);
44+
45+
// start separate DMAs for sending and receiving the data
46+
let sending = tx.write_all(Pin::new(tx_buf), tx_channel);
47+
let receiving = rx.read_all(Pin::new(rx_buf), rx_channel);
48+
49+
// block until all data was transmitted and received
50+
let (mut tx_buf, tx_channel, tx) = sending.wait();
51+
let (rx_buf, rx_channel, rx) = receiving.wait();
52+
53+
assert_eq!(tx_buf, rx_buf);
54+
55+
// After a transfer is finished its parts can be re-used for another one.
56+
tx_buf.copy_from_slice(b"hi again!");
57+
58+
let sending = tx.write_all(tx_buf, tx_channel);
59+
let receiving = rx.read_all(rx_buf, rx_channel);
60+
61+
let (tx_buf, ..) = sending.wait();
62+
let (rx_buf, ..) = receiving.wait();
63+
64+
assert_eq!(tx_buf, rx_buf);
65+
66+
loop {
67+
continue;
68+
}
69+
}

0 commit comments

Comments
 (0)