|
| 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