Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need some help with interrupts #154

Closed
josephpenafiel opened this issue Jul 10, 2019 · 6 comments
Closed

Need some help with interrupts #154

josephpenafiel opened this issue Jul 10, 2019 · 6 comments

Comments

@josephpenafiel
Copy link

josephpenafiel commented Jul 10, 2019

Hello everyone,

I'm trying to test some interrupts in a stm32f302 nucleo board, but I'm having some trouble with the Mutex. When I define one, I get this error:
"calls in statics are limited to constant functions, tuple structs and tuple variants rustc (E0015)"

here's the code I'm trying to test:

`
#![no_main]
#![no_std]
#[allow(unused_extern_crates)]

extern crate panic_halt;
extern crate stm32f30x;

use core::cell::RefCell;
use cortex_m_rt::entry;
// use cortex_m::interrupt::{Mutex, self};
use stm32f30x::{interrupt,Interrupt};

static MY_TIM2: cortex_m::interrupt::Mutex<RefCell<Option<stm32f30x::TIM2>>> = cortex_m::interrupt::Mutex::new(RefCell::new(None)); // <----error
static mut TOOGLE: bool = false;

#[entry]
fn main() -> ! {
let p = cortex_m::Peripherals::take().unwrap();
let cp = stm32f30x::Peripherals::take().unwrap();
let rcc = &cp.RCC;
let gpiob = &cp.GPIOB;
let tim2 = &cp.TIM2;

rcc.apb1enr.write(|w| w.tim2en().set_bit()); // tim2 clock
rcc.ahbenr.write(|w| w.iopben().set_bit()); // pb2 clock

gpiob.moder.write(|w| w.moder13().output());
gpiob.odr.write(|w| w.odr13().set_bit());

tim2.psc.write(|w| unsafe {w.psc().bits(23_999)}); // 24k prescaler
tim2.arr.write(|w| unsafe {w.arrl().bits(1000)}); // auto reload value
tim2.dier.write(|w| w.uie().set_bit());
tim2.cr1.write(|w| w.cen().set_bit());

// interrupt::free(|cs| MY_GPIO.borrow(cs).replace(Some(cp.GPIOB)));
cortex_m::interrupt::free(|cs| MY_TIM2.borrow(cs).replace(Some(cp.TIM2)));

let mut nvic = p.NVIC;
nvic.enable(Interrupt::TIM2);


loop {
    
}

}

#[interrupt]
fn TIM2() {
cortex_m::interrupt::free(|cs| {
let tim2 = MY_TIM2.borrow(cs).borrow();
if tim2.as_ref().unwrap().sr.read().uif().bit_is_set() {
unsafe { TOOGLE = !TOOGLE };
tim2.as_ref().unwrap().sr.write(|w| w.uif().clear_bit());
}
});

}
`

I followed the example from the Rust embedded book in the concurrency section.

thanks in advance

@geomatsi
Copy link

Hi @josephpenafiel
In brief, it should be enough to enable const-fn feature in cortex-m crate:

[dependencies.cortex-m]
version="0.6.0"
features=["const-fn"]

This feature is going to be enabled by default some time in the future: see #153 . As for the embedded-rust book, the appropriate update is on review at the moment: see PR#196.

Regards,
Sergey

@josephpenafiel
Copy link
Author

josephpenafiel commented Jul 10, 2019

thank you that worked, but now I have a new problem. I want to do something simple. Toggle a led everytime a timer interrupt occurs.
I made a Mutex for the timer, since I need to access it in the interrupt handler to clear the interrupt flag. But since all the peripherals moved into the Mutex, I can't access the GPIO anymore.

The compiler tells me this:
let gpiob = &cp.GPIOB; | --------- borrow ofcp.GPIOBoccurs here ... 44 | cortex_m::interrupt::free(|cs| MY_TIM2.borrow(cs).replace(Some(cp.TIM2))); | ^^^^ move out ofcpoccurs here -- move occurs due to use in closure ... 57 | gpiob.odr.write(|w| w.odr13().clear_bit()); | ----- borrow later used here

what's the correct way of doing what I want?

@geomatsi
Copy link

I would suggest to try the following approach: make both TIM2 and GPIO (or LED pin) global shared resources. Then use them in TIM2 handler under interrupt::free mutex.

@josephpenafiel
Copy link
Author

when i do that I get a similar error
--> src/main.rs:47:31 | 27 | let cp = stm32f30x::Peripherals::take().unwrap(); | -- move occurs becausecphas typestm32f30x::Peripherals, which does not implement the Copytrait ... 46 | cortex_m::interrupt::free(|cs| MY_GPIOB.borrow(cs).replace(Some(cp.GPIOB))); | ---- value moved into closure here -- variable moved due to use in closure 47 | cortex_m::interrupt::free(|cs| MY_TIM2.borrow(cs).replace(Some(cp.TIM2))); | ^^^^ value used here after move -- use occurs due to use in closure

@geomatsi
Copy link

Hi @josephpenafiel

Here is an example for BluePill that converts both TIM2 and PC13 into shared resources and uses them in a safe way: safe LED blink from TIM2 irq.

Regards,
Sergey

@josephpenafiel
Copy link
Author

not helpful

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants