|
| 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::{DmaMode, SampleTime, Sequence, ADC}, |
| 8 | + delay::DelayCM, |
| 9 | + dma::{dma1, RxDma, Transfer, W}, |
| 10 | + prelude::*, |
| 11 | + time::Hertz, |
| 12 | +}; |
| 13 | + |
| 14 | +use rtic::app; |
| 15 | + |
| 16 | +const SEQUENCE_LEN: usize = 3; |
| 17 | + |
| 18 | +#[app(device = stm32l4xx_hal::stm32, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)] |
| 19 | +const APP: () = { |
| 20 | + // RTIC app is written in here! |
| 21 | + |
| 22 | + struct Resources { |
| 23 | + transfer: Option<Transfer<W, &'static mut [u16; SEQUENCE_LEN], RxDma<ADC, dma1::C1>>>, |
| 24 | + } |
| 25 | + |
| 26 | + #[init] |
| 27 | + fn init(cx: init::Context) -> init::LateResources { |
| 28 | + let MEMORY = { |
| 29 | + static mut MEMORY: [u16; SEQUENCE_LEN] = [0u16; SEQUENCE_LEN]; |
| 30 | + unsafe { &mut MEMORY } |
| 31 | + }; |
| 32 | + |
| 33 | + rtt_init_print!(); |
| 34 | + |
| 35 | + rprintln!("Hello from init!"); |
| 36 | + |
| 37 | + let cp = cx.core; |
| 38 | + let mut dcb = cp.DCB; |
| 39 | + let mut dwt = cp.DWT; |
| 40 | + |
| 41 | + dcb.enable_trace(); |
| 42 | + dwt.enable_cycle_counter(); |
| 43 | + |
| 44 | + let pac = cx.device; |
| 45 | + |
| 46 | + let mut rcc = pac.RCC.constrain(); |
| 47 | + let mut flash = pac.FLASH.constrain(); |
| 48 | + let mut pwr = pac.PWR.constrain(&mut rcc.apb1r1); |
| 49 | + let dma_channels = pac.DMA1.split(&mut rcc.ahb1); |
| 50 | + |
| 51 | + // |
| 52 | + // Initialize the clocks |
| 53 | + // |
| 54 | + let clocks = rcc |
| 55 | + .cfgr |
| 56 | + .sysclk(Hertz(80_000_000)) |
| 57 | + .freeze(&mut flash.acr, &mut pwr); |
| 58 | + |
| 59 | + let mut delay = DelayCM::new(clocks); |
| 60 | + |
| 61 | + let mut adc = ADC::new( |
| 62 | + pac.ADC1, |
| 63 | + pac.ADC_COMMON, |
| 64 | + &mut rcc.ahb2, |
| 65 | + &mut rcc.ccipr, |
| 66 | + &mut delay, |
| 67 | + ); |
| 68 | + |
| 69 | + let mut temp_pin = adc.enable_temperature(); |
| 70 | + |
| 71 | + let dma1_channel = dma_channels.1; |
| 72 | + |
| 73 | + adc.configure_sequence(&mut temp_pin, Sequence::One, SampleTime::Cycles12_5); |
| 74 | + adc.configure_sequence(&mut temp_pin, Sequence::Two, SampleTime::Cycles247_5); |
| 75 | + adc.configure_sequence(&mut temp_pin, Sequence::Three, SampleTime::Cycles640_5); |
| 76 | + |
| 77 | + // Heapless boxes also work very well as buffers for DMA transfers |
| 78 | + let transfer = Transfer::from_adc(adc, dma1_channel, MEMORY, DmaMode::Oneshot, true); |
| 79 | + |
| 80 | + init::LateResources { |
| 81 | + transfer: Some(transfer), |
| 82 | + } |
| 83 | + } |
| 84 | + |
| 85 | + #[idle] |
| 86 | + fn idle(_cx: idle::Context) -> ! { |
| 87 | + loop { |
| 88 | + cortex_m::asm::nop(); |
| 89 | + } |
| 90 | + } |
| 91 | + |
| 92 | + #[task(binds = DMA1_CH1, resources = [transfer])] |
| 93 | + fn dma1_interrupt(cx: dma1_interrupt::Context) { |
| 94 | + let transfer = cx.resources.transfer; |
| 95 | + if let Some(transfer_val) = transfer.take() { |
| 96 | + let (buffer, rx_dma) = transfer_val.wait(); |
| 97 | + rprintln!("DMA measurements: {:?}", buffer); |
| 98 | + *transfer = Some(Transfer::from_adc_dma( |
| 99 | + rx_dma, |
| 100 | + buffer, |
| 101 | + DmaMode::Oneshot, |
| 102 | + true, |
| 103 | + )); |
| 104 | + } |
| 105 | + } |
| 106 | +}; |
0 commit comments