|
| 1 | +//! Test with |
| 2 | +//! cargo flash --release --features stm32l4x2,rt --chip STM32L452RETx --example lptim_rtic --target thumbv7em-none-eabi |
| 3 | +//! on Nucleo-L452-P board |
| 4 | +#![deny(unsafe_code)] |
| 5 | +#![no_main] |
| 6 | +#![no_std] |
| 7 | +extern crate panic_rtt_target; |
| 8 | + |
| 9 | +use rtt_target::rprintln; |
| 10 | +use stm32l4xx_hal::{ |
| 11 | + flash::ACR, |
| 12 | + gpio::{gpiob::PB13, Output, PushPull, State}, |
| 13 | + lptimer::{ClockSource, Event, LowPowerTimer, LowPowerTimerConfig, PreScaler}, |
| 14 | + pac::LPTIM1, |
| 15 | + prelude::*, |
| 16 | + pwr::Pwr, |
| 17 | + rcc::{ClockSecuritySystem, Clocks, CrystalBypass, RccExt, CFGR}, |
| 18 | + time::U32Ext, |
| 19 | +}; |
| 20 | + |
| 21 | +// this is the LD4 on Nucleo-L452-P |
| 22 | +type Led = PB13<Output<PushPull>>; |
| 23 | +type Timer = LowPowerTimer<LPTIM1>; |
| 24 | + |
| 25 | +pub fn configure_clock_tree(cfgr: CFGR, acr: &mut ACR, pwr: &mut Pwr) -> Clocks { |
| 26 | + cfgr.lse(CrystalBypass::Disable, ClockSecuritySystem::Disable) |
| 27 | + .sysclk(80.mhz()) |
| 28 | + .freeze(acr, pwr) |
| 29 | +} |
| 30 | + |
| 31 | +#[rtic::app(device = stm32l4xx_hal::pac, peripherals = true)] |
| 32 | +const APP: () = { |
| 33 | + struct Resources { |
| 34 | + led: Led, |
| 35 | + lptim: Timer, |
| 36 | + } |
| 37 | + |
| 38 | + #[init] |
| 39 | + fn init(ctx: init::Context) -> init::LateResources { |
| 40 | + rtt_target::rtt_init_print!(); |
| 41 | + |
| 42 | + rprintln!("Init start"); |
| 43 | + let device = ctx.device; |
| 44 | + // Configure the clock. |
| 45 | + let mut rcc = device.RCC.constrain(); |
| 46 | + let mut flash = device.FLASH.constrain(); |
| 47 | + let mut pwr = device.PWR.constrain(&mut rcc.apb1r1); |
| 48 | + let mut gpiob = device.GPIOB.split(&mut rcc.ahb2); |
| 49 | + let clocks = configure_clock_tree(rcc.cfgr, &mut flash.acr, &mut pwr); |
| 50 | + |
| 51 | + // PB13 is a user led on Nucleo-L452-P board |
| 52 | + let led = gpiob.pb13.into_push_pull_output_with_state( |
| 53 | + &mut gpiob.moder, |
| 54 | + &mut gpiob.otyper, |
| 55 | + State::Low, |
| 56 | + ); |
| 57 | + rprintln!("Clocks = {:#?}", clocks); |
| 58 | + let lptim_config = LowPowerTimerConfig::default() |
| 59 | + .clock_source(ClockSource::LSE) |
| 60 | + .prescaler(PreScaler::U1) |
| 61 | + .arr_value(32_768u16); // roughly 1s |
| 62 | + let mut lptim = LowPowerTimer::lptim1( |
| 63 | + device.LPTIM1, |
| 64 | + lptim_config, |
| 65 | + &mut rcc.apb1r1, |
| 66 | + &mut rcc.ccipr, |
| 67 | + clocks, |
| 68 | + ); |
| 69 | + lptim.listen(Event::AutoReloadMatch); |
| 70 | + init::LateResources { lptim, led } |
| 71 | + } |
| 72 | + |
| 73 | + #[task(binds = LPTIM1, resources = [lptim, led])] |
| 74 | + fn timer_tick(mut ctx: timer_tick::Context) { |
| 75 | + let timer_tick::Resources { lptim, led } = ctx.resources; |
| 76 | + if lptim.is_event_triggered(Event::AutoReloadMatch) { |
| 77 | + lptim.clear_event_flag(Event::AutoReloadMatch); |
| 78 | + rprintln!("LPTIM1 tick"); |
| 79 | + |
| 80 | + if led.is_set_high().unwrap() { |
| 81 | + led.set_low().unwrap(); |
| 82 | + } else { |
| 83 | + led.set_high().unwrap(); |
| 84 | + } |
| 85 | + } |
| 86 | + } |
| 87 | + |
| 88 | + #[idle] |
| 89 | + fn idle(_ctx: idle::Context) -> ! { |
| 90 | + loop { |
| 91 | + // See https://github.com/probe-rs/probe-rs/issues/350 |
| 92 | + core::hint::spin_loop(); |
| 93 | + } |
| 94 | + } |
| 95 | + |
| 96 | + extern "C" { |
| 97 | + fn LCD(); |
| 98 | + } |
| 99 | +}; |
0 commit comments