Skip to content

How to clear interrupt with peripheral handle #307

@dunajski

Description

@dunajski

Few weeks ago I started to learn Rust Embedded.
Now I'm stuck, and I would like to ask you for help. So..

I wanted to use TIM3 in my code to change variable (in future peripheral state) and clear (unpend?) interrupt via registers inside ISR.

In C I did something like this inside ISR:

void TIM3_IRQHandler(void)
{
  if (TIM3->SR & TIM_SR_UIF)
  {
    TIM3->SR &= ~(TIM_SR_UIF);
  }
}

..and now I'm stuck to do this in Rust.
At first I show what I've done so far.

#![no_std]
#![no_main]

use panic_halt as _;

use cortex_m_rt::entry;

use core::{cell::RefCell};
use core::ops::DerefMut;
use cortex_m::interrupt::{self, Mutex};
use stm32g0::stm32g071::{self, Interrupt, NVIC, TIM3};

static G_TIM: Mutex<RefCell<Option<stm32g071::TIM3>>> =
    Mutex::new(RefCell::new(None));

#[entry]
fn main() -> ! {
    let p = stm32g071::Peripherals::take().unwrap();

    let rcc_r = &p.RCC;

    let timer_r = &p.TIM3;

    let tim3 = p.TIM3;

    unsafe {
        NVIC::unmask(Interrupt::TIM3);
    };

    rcc_r.apbenr1.write(|w| w.tim3en().set_bit());

    prepare_timer3(timer_r);

    interrupt::free(|cs| {
        G_TIM.borrow(cs).replace(Some(tim3))
    });

    loop {
    }
}

fn prepare_timer3(tim3_r_handle: &TIM3) {
    tim3_r_handle.cr1.write(|w| w.cen().clear_bit());
    tim3_r_handle.psc.write(|w| unsafe { w.psc().bits(16000) });
    tim3_r_handle.arr.write(|w| unsafe { w.arr_l().bits(100) });
    tim3_r_handle.egr.write(|w| w.ug().set_bit());
    tim3_r_handle.dier.write(|w| w.uie().set_bit());
    tim3_r_handle.cr1.write(|w| w.cen().set_bit());
}

#[interrupt]
fn TIM3() {
    interrupt::free(|cs| {
        if let Some(ref mut tim3) =  G_TIM.borrow(cs).borrow_mut().deref_mut() {
            tim3.sr.write(|w| w.uif().clear_bit());
        }
    })
}

And I get this compilation error:

error: cannot find attribute `interrupt` in this scope
  --> src/main.rs:51:3
   |
51 | #[interrupt]
   |   ^^^^^^^^^
   |
   = note: consider importing one of these items:
           cortex_m_rt::interrupt
           crate::stm32g071::interrupt
           stm32g0::stm32g071::interrupt
note: `interrupt` is imported here, but it is a module, not an attribute
  --> src/main.rs:10:27
   |
10 | use cortex_m::interrupt::{self, Mutex};
   |                           ^^^^

error: could not compile `blink-nucleo-g0` due to previous error

I have problem how to resolve those dependency problem.
Could you tell me also that what I did with this Mutex G_TIM is fine?
I mean I did this after read this article: https://docs.rust-embedded.org/book/concurrency/#sharing-peripherals
I also read this https://users.rust-lang.org/t/rust-embedded-stm32f303-timer-interrupt-hanging/40323 but I don't want to use hal crates.

I also asked at Stackoverflow: how-to-clear-interrupt-with-perpiheral-handle-embedded-rust
... and Rust forum: https://users.rust-lang.org/t/how-to-clear-interrupt-with-peripheral-handle/67214

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions