Skip to content

Commit b0aaa37

Browse files
authored
Merge pull request #86 from ra-kete/dma
Initial DMA support
2 parents 8232126 + ffd73aa commit b0aaa37

File tree

7 files changed

+956
-63
lines changed

7 files changed

+956
-63
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1010
### Added
1111

1212
- Implement `InputPin` for `Output<OpenDrain>` pins ([#114](https://github.com/stm32-rs/stm32f3xx-hal/pull/114))
13+
- Support for safe one-shot DMA transfers ([#86](https://github.com/stm32-rs/stm32f3xx-hal/pull/86))
14+
- DMA support for serial reception and transmission ([#86](https://github.com/stm32-rs/stm32f3xx-hal/pull/86))
1315

1416
### Fixed
1517

Cargo.toml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,21 @@ version = "0.2"
3030
features = ["const-fn"]
3131

3232
[dependencies.cast]
33-
default-features = false
3433
version = "0.2"
35-
36-
[dependencies.void]
3734
default-features = false
35+
36+
[dependencies.stable_deref_trait]
3837
version = "1"
38+
default-features = false
3939

4040
[dependencies.stm32-usbd]
4141
version = "0.5"
4242
optional = true
4343

44+
[dependencies.void]
45+
version = "1"
46+
default-features = false
47+
4448
[dev-dependencies]
4549
panic-semihosting = "0.5"
4650
usb-device = "0.2"
@@ -102,3 +106,7 @@ required-features = ["rt", "stm32f303xc", "stm32-usbd"]
102106
[[example]]
103107
name = "spi"
104108
required-features = ["stm32f303"]
109+
110+
[[example]]
111+
name = "serial_dma"
112+
required-features = ["stm32f303"]

examples/serial_dma.rs

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

0 commit comments

Comments
 (0)