Skip to content

Commit f7ba5f8

Browse files
committed
Added example - TIM2 triggering ADC conversion of one sample
1 parent f49bc15 commit f7ba5f8

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

examples/adc_dma_trigger_tim2.rs

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#![no_main]
2+
#![no_std]
3+
4+
use panic_rtt_target as _;
5+
use rtt_target::{rprintln, rtt_init_print};
6+
use stm32l4xx_hal::{
7+
adc::{config, DmaMode, SampleTime, Sequence, ADC},
8+
delay::DelayCM,
9+
dma::{dma1, RxDma, Transfer, W},
10+
timer::{Timer, Event, MasterMode},
11+
prelude::*,
12+
pac::{TIM2},
13+
};
14+
15+
use rtic::app;
16+
17+
const SEQUENCE_LEN: usize = 8;
18+
19+
#[app(device = stm32l4xx_hal::stm32, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)]
20+
const APP: () = {
21+
// RTIC app is written in here!
22+
23+
struct Resources {
24+
transfer: Option<Transfer<W, &'static mut [u16; SEQUENCE_LEN], RxDma<ADC, dma1::C1>>>,
25+
timer: Timer<TIM2>,
26+
}
27+
28+
#[init]
29+
fn init(cx: init::Context) -> init::LateResources {
30+
let MEMORY = {
31+
static mut MEMORY: [u16; SEQUENCE_LEN] = [0u16; SEQUENCE_LEN];
32+
unsafe { &mut MEMORY }
33+
};
34+
35+
rtt_init_print!();
36+
37+
rprintln!("Hello from init!");
38+
39+
let cp = cx.core;
40+
let mut dcb = cp.DCB;
41+
let mut dwt = cp.DWT;
42+
43+
dcb.enable_trace();
44+
dwt.enable_cycle_counter();
45+
46+
let pac = cx.device;
47+
48+
let mut rcc = pac.RCC.constrain();
49+
let mut flash = pac.FLASH.constrain();
50+
let mut pwr = pac.PWR.constrain(&mut rcc.apb1r1);
51+
let dma_channels = pac.DMA1.split(&mut rcc.ahb1);
52+
53+
//
54+
// Initialize the clocks
55+
//
56+
let clocks = rcc.cfgr.sysclk(80.MHz()).freeze(&mut flash.acr, &mut pwr);
57+
58+
let mut delay = DelayCM::new(clocks);
59+
60+
let mut adc = ADC::new(
61+
pac.ADC1,
62+
pac.ADC_COMMON,
63+
&mut rcc.ahb2,
64+
&mut rcc.ccipr,
65+
&mut delay,
66+
config::ExternalTriggerConfig(
67+
config::TriggerMode::RisingEdge,
68+
config::ExternalTrigger::Tim_2_trgo,
69+
),
70+
);
71+
72+
let mut timer_adc_trg = Timer::tim2(pac.TIM2, 1.Hz(), clocks, &mut rcc.apb1r1);
73+
timer_adc_trg.master_mode(MasterMode::Update);
74+
timer_adc_trg.listen(Event::TimeOut);
75+
76+
let dma1_channel = dma_channels.1;
77+
78+
let mut gpioa = pac.GPIOA.split(&mut rcc.ahb2);
79+
let mut a1 = gpioa.pa0.into_analog(&mut gpioa.moder, &mut gpioa.pupdr);
80+
81+
adc.configure_sequence(&mut a1, Sequence::One, SampleTime::Cycles12_5);
82+
83+
// Heapless boxes also work very well as buffers for DMA transfers
84+
let transfer = Transfer::from_adc(adc, dma1_channel, MEMORY, DmaMode::Oneshot, true, false);
85+
86+
init::LateResources {
87+
transfer: Some(transfer),
88+
timer: timer_adc_trg,
89+
}
90+
}
91+
92+
#[idle]
93+
fn idle(_cx: idle::Context) -> ! {
94+
loop {
95+
cortex_m::asm::nop();
96+
}
97+
}
98+
99+
#[task(binds = DMA1_CH1, resources = [transfer])]
100+
fn dma1_interrupt(cx: dma1_interrupt::Context) {
101+
let transfer = cx.resources.transfer;
102+
if let Some(transfer_val) = transfer.take() {
103+
let (buffer, rx_dma) = transfer_val.wait();
104+
rprintln!("DMA measurements: {:?}", buffer);
105+
*transfer = Some(Transfer::from_adc_dma(
106+
rx_dma,
107+
buffer,
108+
DmaMode::Oneshot,
109+
true,
110+
false,
111+
));
112+
}
113+
}
114+
115+
#[task(binds = TIM2, resources = [timer])]
116+
fn tim2_interrupt(cx: tim2_interrupt::Context) {
117+
let timer = cx.resources.timer;
118+
timer.clear_interrupt(stm32l4xx_hal::timer::Event::TimeOut);
119+
rprintln!("TIM2 int - ADC trigger");
120+
}
121+
};

0 commit comments

Comments
 (0)