1
- // blinky timer using interrupts on TIM2
2
- //
3
- // This demo based off of the following demo:
4
- // - https://github.com/stm32-rs/stm32f0xx-hal/blob/master/examples/blinky_timer_irq.rs
5
- // with some information about STM32F1 interrupts/peripherals from:
6
- // - https://github.com/geomatsi/rust-blue-pill-tests/blob/master/src/bin/blink-timer-irq-safe.rs
1
+ //! blinky timer using interrupts on TIM2
2
+ //!
3
+ //! This assumes that a LED is connected to pc13 as is the case on the blue pill board.
4
+ //!
5
+ //! Please note according to RM0008:
6
+ //! "Due to the fact that the switch only sinks a limited amount of current (3 mA), the use of
7
+ //! GPIOs PC13 to PC15 in output mode is restricted: the speed has to be limited to 2MHz with
8
+ //! a maximum load of 30pF and these IOs must not be used as a current source (e.g. to drive a LED)"
7
9
8
10
#![ no_main]
9
11
#![ no_std]
@@ -13,15 +15,16 @@ use panic_halt as _;
13
15
use stm32f1xx_hal as hal;
14
16
15
17
use crate :: hal:: {
16
- gpio:: * ,
18
+ gpio:: { gpioc , Output , PushPull } ,
17
19
pac:: { interrupt, Interrupt , Peripherals , TIM2 } ,
18
20
prelude:: * ,
19
- timer:: * ,
21
+ timer:: { CountDownTimer , Event , Timer } ,
20
22
} ;
21
23
22
24
use core:: cell:: RefCell ;
23
- use cortex_m:: { asm:: wfi, interrupt:: Mutex , peripheral :: Peripherals as c_m_Peripherals } ;
25
+ use cortex_m:: { asm:: wfi, interrupt:: Mutex } ;
24
26
use cortex_m_rt:: entry;
27
+ use embedded_hal:: digital:: v2:: OutputPin ;
25
28
26
29
// NOTE You can uncomment 'hprintln' here and in the code below for a bit more
27
30
// verbosity at runtime, at the cost of throwing off the timing of the blink
@@ -59,55 +62,44 @@ fn TIM2() {
59
62
} )
60
63
} ) ;
61
64
62
- //hprintln!("TIM2 IRQ fired").unwrap();
63
- led. toggle ( ) . ok ( ) ;
64
- tim. wait ( ) . ok ( ) ;
65
+ let _ = led. toggle ( ) ;
66
+ let _ = tim. wait ( ) ;
65
67
}
66
68
67
69
#[ entry]
68
70
fn main ( ) -> ! {
69
- if let ( Some ( dp) , Some ( cp) ) = ( Peripherals :: take ( ) , c_m_Peripherals:: take ( ) ) {
70
- cortex_m:: interrupt:: free ( move |cs| {
71
- let mut rcc = dp. RCC . constrain ( ) ;
72
- let mut flash = dp. FLASH . constrain ( ) ;
73
- let clocks = rcc
74
- . cfgr
75
- . sysclk ( 8 . mhz ( ) )
76
- . pclk1 ( 8 . mhz ( ) )
77
- . freeze ( & mut flash. acr ) ;
78
-
79
- // Configure PC13 pin to blink LED
80
- let mut gpioc = dp. GPIOC . split ( & mut rcc. apb2 ) ;
81
- let led = gpioc. pc13 . into_push_pull_output ( & mut gpioc. crh ) ;
82
-
83
- // Move the pin into our global storage
84
- * G_LED . borrow ( cs) . borrow_mut ( ) = Some ( led) ;
85
-
86
- // Set up a timer expiring after 1s
87
- let mut timer = Timer :: tim2 ( dp. TIM2 , & clocks, & mut rcc. apb1 ) . start_count_down ( 1 . hz ( ) ) ;
88
-
89
- // Generate an interrupt when the timer expires
90
- timer. listen ( Event :: Update ) ;
91
-
92
- // Move the timer into our global storage
93
- * G_TIM . borrow ( cs) . borrow_mut ( ) = Some ( timer) ;
94
-
95
- // Enable TIM2 IRQ, set prio 1 and clear any pending IRQs
96
- let mut nvic = cp. NVIC ;
97
- // Calling 'set_priority()' and 'unmask()' requires 'unsafe {}'
98
- // - https://docs.rs/stm32f1xx-hal/0.5.3/stm32f1xx_hal/stm32/struct.NVIC.html#method.set_priority
99
- unsafe {
100
- nvic. set_priority ( Interrupt :: TIM2 , 1 ) ;
101
- cortex_m:: peripheral:: NVIC :: unmask ( Interrupt :: TIM2 ) ;
102
- }
103
- // Clear the interrupt state
104
- cortex_m:: peripheral:: NVIC :: unpend ( Interrupt :: TIM2 ) ;
105
- } ) ;
71
+ let dp = Peripherals :: take ( ) . unwrap ( ) ;
72
+
73
+ let mut rcc = dp. RCC . constrain ( ) ;
74
+ let mut flash = dp. FLASH . constrain ( ) ;
75
+ let clocks = rcc
76
+ . cfgr
77
+ . sysclk ( 8 . mhz ( ) )
78
+ . pclk1 ( 8 . mhz ( ) )
79
+ . freeze ( & mut flash. acr ) ;
80
+
81
+ // Configure PC13 pin to blink LED
82
+ let mut gpioc = dp. GPIOC . split ( & mut rcc. apb2 ) ;
83
+ let mut led = gpioc. pc13 . into_push_pull_output ( & mut gpioc. crh ) ;
84
+ let _ = led. set_high ( ) ; // Turn off
85
+
86
+ // Move the pin into our global storage
87
+ cortex_m:: interrupt:: free ( |cs| * G_LED . borrow ( cs) . borrow_mut ( ) = Some ( led) ) ;
88
+
89
+ // Set up a timer expiring after 1s
90
+ let mut timer = Timer :: tim2 ( dp. TIM2 , & clocks, & mut rcc. apb1 ) . start_count_down ( 1 . hz ( ) ) ;
91
+
92
+ // Generate an interrupt when the timer expires
93
+ timer. listen ( Event :: Update ) ;
94
+
95
+ // Move the timer into our global storage
96
+ cortex_m:: interrupt:: free ( |cs| * G_TIM . borrow ( cs) . borrow_mut ( ) = Some ( timer) ) ;
97
+
98
+ unsafe {
99
+ cortex_m:: peripheral:: NVIC :: unmask ( Interrupt :: TIM2 ) ;
106
100
}
107
101
108
- //hprintln!("Entering main loop...").unwrap();
109
102
loop {
110
- // From 'cortex_m::asm::wfi'
111
103
wfi ( ) ;
112
104
}
113
105
}
0 commit comments