timer working

This commit is contained in:
Priec
2025-10-23 12:08:59 +02:00
parent 7da55196e7
commit 73c45bff85
11 changed files with 1714 additions and 0 deletions

84
time_meas/src/bin/main.rs Normal file
View File

@@ -0,0 +1,84 @@
// src/bin/main.rs
#![no_std]
#![no_main]
use core::sync::atomic::{AtomicUsize, Ordering};
use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::pac;
use embassy_stm32::interrupt::InterruptExt;
use embassy_stm32::timer::low_level::{CountingMode, Timer as LLTimer};
use embassy_stm32::time::khz;
use embassy_stm32::interrupt;
use {defmt_rtt as _, panic_probe as _};
// Pointer to the local `counter` so the ISR can read it with zero per-iteration overhead.
static COUNTER_PTR: AtomicUsize = AtomicUsize::new(0);
// NVIC handler for TIM2
#[interrupt]
fn TIM2() {
// Clear UIF, stop the timer
pac::TIM2.sr().modify(|r| r.set_uif(false));
pac::TIM2.cr1().modify(|r| r.set_cen(false));
// Snapshot the counter that the loop has been incrementing
let ptr = COUNTER_PTR.load(Ordering::Relaxed) as *const u32;
let count = unsafe { core::ptr::read_volatile(ptr) };
info!("10 seconds elapsed, counter = {}", count);
// Halt
loop {
cortex_m::asm::bkpt();
}
}
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
info!("Start");
let p = embassy_stm32::init(Default::default());
// Configure TIM2
let mut tim2 = LLTimer::new(p.TIM2);
tim2.stop();
tim2.set_counting_mode(CountingMode::EdgeAlignedUp);
// Make the timer tick at 10 kHz. Driver derives PSC from RCC, so timing is exact.
tim2.set_tick_freq(khz(10));
// 10 seconds => 10_000 ticks/s * 10 s = 100_000 ticks. ARR is inclusive: set to 100_000 - 1.
tim2.set_max_compare_value(100_000 - 1);
// One-pulse mode (auto-stop after the first update event)
tim2.regs_core().cr1().modify(|r| r.set_opm(true));
// Ensure no pending UIF from the UG we generated during PSC/ARR programming.
// Important: do this BEFORE enabling UIE/NVIC to avoid an immediate ISR.
let _ = tim2.clear_update_interrupt();
// Enable update interrupt, reset counter to 0. Do not start yet.
tim2.enable_update_interrupt(true);
tim2.reset();
// Expose the address of the loop counter BEFORE enabling the NVIC so the ISR
// never runs before COUNTER_PTR is valid.
let mut counter: u32 = 0;
COUNTER_PTR.store(&counter as *const u32 as usize, Ordering::Relaxed);
// Unpend and enable NVIC for TIM2, then start the timer.
unsafe {
embassy_stm32::interrupt::TIM2.unpend();
embassy_stm32::interrupt::TIM2.enable();
}
tim2.start();
// Tight CPU loop for benchmarking
loop {
counter = counter.wrapping_add(1);
if counter % 10000 == 0 {
info!("CPU doing other work: {}", counter);
}
}
}

1
time_meas/src/lib.rs Normal file
View File

@@ -0,0 +1 @@
#![no_std]