STM32F103C8T6 (blue pill) and GPIO interrupts

I’m making small progress of getting around with Rust embedded, but I’ve tried endlessly to simply have an interrupt that fires when a button connected to ground and a digital pin (I use PA1) on my blue pill board is pressed. The code to read the state of the pin in the main loop works.
I have the following code:

fn main() -> ! {
    let cp = cortex_m::Peripherals::take().unwrap();
    let dp = pac::Peripherals::take().unwrap();

    let mut nvic = cp.NVIC;
    let mut gpioa = dp.GPIOA.split(&mut rcc.apb2);
    let pin1 = gpioa.pa1.into_pull_up_input(&mut gpioa.crl);
    loop {
        hprintln!("Button pressed: {:?}", pin1.is_high()).unwrap();
        cortex_m::asm::delay(1 * 100_000_000);

fn EXTI1() {
    hprintln!("Interrupt!!!").unwrap(); // does not work...

For the moment I’m not using RTFM, since I wanted to understand the basics first…

Any help or pointers are much appreciated. TIA!

I’m no expert on STM32 external interrupts, but I would guess that in addition you need to configure the EXTI unit (see the reference manual).

Yes, I need to set EXTI_IMR (Interrupt mask register), EXTI_RTSR (rising trigger), EXTI_FTSR (falling trigger).

The question is how to do it in Rust. The fact that the device crates are generated and not really documented does not make it easy for newbies like me.

Which one of these do I need?

  • stm32f1xx_hal::device::exti::IMR
  • stm32f1xx_hal::pac::exti::IMR
  • stm32f1xx_hal::stm32::exti::IMR

And, how do I obtain ‘values’ of these types?

I’ve found this blog post, but it seems to be outdated, because I can’t get it to work with stm32f1xx-hal version 0.3.0.

Nevermind, I’m a step further now. The code I needed before the main loop was:

    let exti = dp.EXTI;
    exti.imr.write(|w| w.mr1().set_bit());
    exti.ftsr.write(|w| w.tr1().set_bit());

Problem now is that I need to clear the EXTI_PR, since my interrupt keeps being called continuously. Which requires access to the EXTI from the interrupt, which probably requires the mutex hack used in the blog post I’ve referenced in my previous comment…

I’m trying to use a timer (TIM2) to capture input and have it increase the timer’s counter to increase when a rising edge is detected on a pin. I’m using the STM RM0008 Reference manual to determine which registers need to be set.

However, when I for example try to write to the CCMR1 register:

        let tim2 = device.TIM2;
        tim2.ccmr1_input.write(|w| {

I get unknown field rustc(E0609). What am I missing? Does somebody have an example for Input Capture mode on a STM32?

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.