11
11
// you can put a breakpoint on `rust_begin_unwind` to catch panics
12
12
use panic_halt as _;
13
13
14
- use cortex_m:: asm:: wfi;
15
14
use rtfm:: app;
16
15
17
16
use stm32f1xx_hal:: {
@@ -22,80 +21,86 @@ use stm32f1xx_hal::{
22
21
} ;
23
22
use embedded_hal:: digital:: v2:: OutputPin ;
24
23
25
- #[ app( device = stm32f1xx_hal:: pac) ]
24
+ #[ app( device = stm32f1xx_hal:: pac, peripherals = true ) ]
26
25
const APP : ( ) = {
27
26
28
- static mut LED : PC13 < Output < PushPull > > = ( ) ;
29
- static mut TIMER_HANDLER : CountDownTimer < pac:: TIM1 > = ( ) ;
30
- static mut LED_STATE : bool = false ;
31
-
32
- #[ init]
33
- fn init ( ) -> init:: LateResources {
27
+ struct Resources {
28
+ led : PC13 < Output < PushPull > > ,
29
+ timer_handler : CountDownTimer < pac:: TIM1 > ,
30
+
31
+ #[ init( false ) ]
32
+ led_state : bool ,
33
+ }
34
34
35
+ #[ init]
36
+ fn init ( cx : init:: Context ) -> init:: LateResources {
35
37
// Take ownership over the raw flash and rcc devices and convert them into the corresponding
36
38
// HAL structs
37
- let mut flash = device. FLASH . constrain ( ) ;
38
- let mut rcc = device. RCC . constrain ( ) ;
39
+ let mut flash = cx . device . FLASH . constrain ( ) ;
40
+ let mut rcc = cx . device . RCC . constrain ( ) ;
39
41
40
42
// Freeze the configuration of all the clocks in the system and store the frozen frequencies
41
43
// in `clocks`
42
44
let clocks = rcc. cfgr . freeze ( & mut flash. acr ) ;
43
45
44
46
// Acquire the GPIOC peripheral
45
- let mut gpioc = device. GPIOC . split ( & mut rcc. apb2 ) ;
47
+ let mut gpioc = cx . device . GPIOC . split ( & mut rcc. apb2 ) ;
46
48
47
49
// Configure gpio C pin 13 as a push-pull output. The `crh` register is passed to the
48
50
// function in order to configure the port. For pins 0-7, crl should be passed instead
49
51
let led = gpioc. pc13 . into_push_pull_output_with_state ( & mut gpioc. crh , State :: High ) ;
50
52
// Configure the syst timer to trigger an update every second and enables interrupt
51
- let mut timer = Timer :: tim1 ( device. TIM1 , & clocks, & mut rcc. apb2 )
53
+ let mut timer = Timer :: tim1 ( cx . device . TIM1 , & clocks, & mut rcc. apb2 )
52
54
. start_count_down ( 1 . hz ( ) ) ;
53
55
timer. listen ( Event :: Update ) ;
54
56
55
57
// Init the static resources to use them later through RTFM
56
58
init:: LateResources {
57
- LED : led,
58
- TIMER_HANDLER : timer,
59
+ led,
60
+ timer_handler : timer,
59
61
}
60
62
}
61
63
64
+ // Optional.
65
+ //
66
+ // https://rtfm.rs/0.5/book/en/by-example/app.html#idle
67
+ // > When no idle function is declared, the runtime sets the SLEEPONEXIT bit and then
68
+ // > sends the microcontroller to sleep after running init.
62
69
#[ idle]
63
- fn idle ( ) -> ! {
64
-
70
+ fn idle ( _cx : idle:: Context ) -> ! {
65
71
loop {
66
- // Waits for interrupt
67
- wfi ( ) ;
72
+ cortex_m:: asm:: wfi ( ) ;
68
73
}
69
74
}
70
75
71
- #[ interrupt ( priority = 1 , resources = [ LED , TIMER_HANDLER , LED_STATE ] ) ]
72
- fn TIM1_UP ( ) {
76
+ #[ task ( binds = TIM1_UP , priority = 1 , resources = [ led , timer_handler , led_state ] ) ]
77
+ fn tick ( cx : tick :: Context ) {
73
78
// Depending on the application, you could want to delegate some of the work done here to
74
79
// the idle task if you want to minimize the latency of interrupts with same priority (if
75
80
// you have any). That could be done with some kind of machine state, etc.
76
81
77
82
// Count used to change the timer update frequency
78
83
static mut COUNT : u8 = 0 ;
79
84
80
- if * resources. LED_STATE {
81
- // Uses resourcers managed by rtfm to turn led off (on bluepill)
82
- resources. LED . set_high ( ) . unwrap ( ) ;
83
- * resources. LED_STATE = false ;
85
+ if * cx . resources . led_state {
86
+ // Uses resources managed by rtfm to turn led off (on bluepill)
87
+ cx . resources . led . set_high ( ) . unwrap ( ) ;
88
+ * cx . resources . led_state = false ;
84
89
} else {
85
- resources. LED . set_low ( ) . unwrap ( ) ;
86
- * resources. LED_STATE = true ;
90
+ cx . resources . led . set_low ( ) . unwrap ( ) ;
91
+ * cx . resources . led_state = true ;
87
92
}
88
93
* COUNT += 1 ;
89
94
90
95
if * COUNT == 4 {
91
96
// Changes timer update frequency
92
- resources. TIMER_HANDLER . start ( 2 . hz ( ) ) ;
97
+ cx . resources . timer_handler . start ( 2 . hz ( ) ) ;
93
98
} else if * COUNT == 12 {
94
- resources. TIMER_HANDLER . start ( 1 . hz ( ) ) ;
99
+ cx . resources . timer_handler . start ( 1 . hz ( ) ) ;
95
100
* COUNT = 0 ;
96
101
}
97
102
98
103
// Clears the update flag
99
- resources. TIMER_HANDLER . clear_update_interrupt_flag ( ) ;
104
+ cx . resources . timer_handler . clear_update_interrupt_flag ( ) ;
100
105
}
101
106
} ;
0 commit comments