Skip to content

Commit

Permalink
Add example for ADC DMA. Update changelog.
Browse files Browse the repository at this point in the history
  • Loading branch information
matoushybl committed Apr 18, 2021
1 parent 7f674b9 commit 2d53bde
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

- Update the sdio driver to match the changes in the PAC
- Update README.md with current information
- Add possibility to use DMA with the ADC abstraction, add example for ADC with DMA

## [v0.9.0] - 2021-04-04

Expand Down
44 changes: 24 additions & 20 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ edition = "2018"

authors = ["Daniel Egger <daniel@eggers-club.de>"]
categories = [
"embedded",
"hardware-support",
"no-std",
"embedded",
"hardware-support",
"no-std",
]
description = "Peripheral access API for STM32F4 series microcontrollers"
documentation = "https://docs.rs/stm32f4xx-hal"
keywords = [
"arm",
"cortex-m",
"stm32f4xx",
"hal",
"arm",
"cortex-m",
"stm32f4xx",
"hal",
]
license = "0BSD"
name = "stm32f4xx-hal"
Expand All @@ -26,32 +26,32 @@ features = ["stm32f429", "rt", "usb_fs", "can"]
targets = ["thumbv7em-none-eabihf"]

[dependencies]
bxcan = { version = ">=0.4, <0.6", optional = true }
bare-metal = {version = "1"}
bxcan = {version = ">=0.4, <0.6", optional = true}
cast = {default-features = false, version = "0.2.2"}
cortex-m = "0.7"
cortex-m-rt = "0.6.10"
embedded-dma = "0.1.2"
embedded-hal = {features = ["unproven"], version = "0.2.3"}
nb = "1"
rand_core = "0.6"
rtcc = "0.2"
sdio-host = {version = "0.5.0", optional = true}
stm32f4 = "0.13"
synopsys-usb-otg = { version = "0.2.0", features = ["cortex-m"], optional = true }
sdio-host = { version = "0.5.0", optional = true }
embedded-dma = "0.1.2"
bare-metal = { version = "1" }
cast = { default-features = false, version = "0.2.2" }
void = { default-features = false, version = "1.0.2" }
embedded-hal = { features = ["unproven"], version = "0.2.3" }
synopsys-usb-otg = {version = "0.2.0", features = ["cortex-m"], optional = true}
void = {default-features = false, version = "1.0.2"}

[dev-dependencies]
panic-semihosting = "0.5.3"
arrayvec = {version = "0.5.1", default-features = false}
cortex-m-rtic = "0.5.6"
cortex-m-semihosting = "0.3.3"
arrayvec = { version = "0.5.1", default-features = false }
embedded-graphics = "0.6.2"
micromath = "1.0.0"
panic-halt = "0.2.0"
panic-semihosting = "0.5.3"
ssd1306 = "0.5"
embedded-graphics = "0.6.2"
usb-device = "0.2.5"
usbd-serial = "0.1.0"
micromath = "1.0.0"
cortex-m-rtic = "0.5.6"

[features]
device-selected = []
Expand Down Expand Up @@ -139,3 +139,7 @@ required-features = ["can", "stm32f405"]
[[example]]
name = "rtic"
required-features = ["rt", "stm32f407"]

[[example]]
name = "adc_dma_rtic"
required-features = ["rt", "stm32f401"]
113 changes: 113 additions & 0 deletions examples/adc_dma_rtic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#![no_std]
#![no_main]

use cortex_m_semihosting::hprintln;
use panic_semihosting as _;

use rtic::cyccnt::U32Ext;

use stm32f4xx_hal::{
adc::{
config::{AdcConfig, Dma, SampleTime, Scan, Sequence},
Adc, Temperature,
},
dma::{config::DmaConfig, Channel0, PeripheralToMemory, Stream0, StreamsTuple, Transfer},
prelude::*,
signature::{VtempCal110, VtempCal30},
stm32,
stm32::{ADC1, DMA2},
};

const POLLING_PERIOD: u32 = 168_000_000 / 2;

type DMATransfer =
Transfer<Stream0<DMA2>, Channel0, Adc<ADC1>, PeripheralToMemory, &'static mut [u16; 2]>;

#[rtic::app(device = stm32f4xx_hal::stm32, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)]
const APP: () = {
struct Resources {
transfer: DMATransfer,
}

#[init(schedule=[polling])]
fn init(cx: init::Context) -> init::LateResources {
let device: stm32::Peripherals = cx.device;

let rcc = device.RCC.constrain();
let _clocks = rcc
.cfgr
.use_hse(25.mhz())
.require_pll48clk()
.sysclk(84.mhz())
.hclk(84.mhz())
.pclk1(42.mhz())
.pclk2(84.mhz())
.freeze();

let gpiob = device.GPIOB.split();
let voltage = gpiob.pb1.into_analog();

let dma = StreamsTuple::new(device.DMA2);

let config = DmaConfig::default()
.transfer_complete_interrupt(true)
.memory_increment(true)
.double_buffer(true);

let adc_config = AdcConfig::default()
.dma(Dma::Continuous)
.scan(Scan::Enabled);

let mut adc = Adc::adc1(device.ADC1, true, adc_config);
adc.configure_channel(&Temperature, Sequence::One, SampleTime::Cycles_480);
adc.configure_channel(&voltage, Sequence::Two, SampleTime::Cycles_480);
adc.enable_temperature_and_vref();

let first_buffer = cortex_m::singleton!(: [u16; 2] = [0; 2]).unwrap();
let second_buffer = cortex_m::singleton!(: [u16; 2] = [0; 2]).unwrap();
let transfer = Transfer::init(dma.0, adc, first_buffer, Some(second_buffer), config);

let now = cx.start;
cx.schedule.polling(now + POLLING_PERIOD.cycles()).unwrap();

init::LateResources { transfer }
}

#[task(resources = [transfer], schedule = [polling])]
fn polling(cx: polling::Context) {
let transfer: &mut DMATransfer = cx.resources.transfer;
transfer.start(|adc| {
adc.start_conversion();
});

cx.schedule
.polling(cx.scheduled + POLLING_PERIOD.cycles())
.unwrap();
}

#[task(binds = DMA2_STREAM0, resources = [transfer])]
fn dma(cx: dma::Context) {
let transfer: &mut DMATransfer = cx.resources.transfer;

let result = unsafe {
transfer.next_transfer_with(|data, _| {
let raw_temp = data[0];
let raw_volt = data[1];
(data, (raw_temp, raw_volt))
})
}
.unwrap();

let cal30 = VtempCal30::get().read() as f32;
let cal110 = VtempCal110::get().read() as f32;

let temperature = (110.0 - 30.0) * ((result.0 as f32) - cal30) / (cal110 - cal30) + 30.0;
let voltage = (result.1 as f32) / ((2_i32.pow(12) - 1) as f32) * 3.3;

hprintln!("temperature: {}, voltage: {}", temperature, voltage).unwrap();
}

extern "C" {
fn EXTI0();
}
};

0 comments on commit 2d53bde

Please sign in to comment.