@@ -70,6 +70,31 @@ impl PWR {
70
70
/// Returns a struct that can be used to enter Sleep mode
71
71
pub fn sleep_mode < ' r > ( & ' r mut self , scb : & ' r mut SCB ) -> SleepMode < ' r > {
72
72
SleepMode {
73
+ pwr : & mut self . 0 ,
74
+ scb,
75
+ }
76
+ }
77
+
78
+ /// Returns a struct that can be used to enter low-power sleep mode
79
+ ///
80
+ /// # Panics
81
+ ///
82
+ /// To enter low-power sleep mode, the system clock frequency should not
83
+ /// exceed the MSI frequency range 1 (131.072 kHz). This method will panic,
84
+ /// if that is the case.
85
+ pub fn low_power_sleep_mode < ' r > ( & ' r mut self ,
86
+ scb : & ' r mut SCB ,
87
+ rcc : & mut Rcc ,
88
+ )
89
+ -> LowPowerSleepMode < ' r >
90
+ {
91
+ // Panic, if system clock frequency is outside of allowed range. See
92
+ // STM32L0x1/STM32L0x2/STM32L0x3 reference manuals, sections 6.3.8 and
93
+ // 7.2.3.
94
+ assert ! ( rcc. clocks. sys_clk( ) . 0 <= 131_072 ) ;
95
+
96
+ LowPowerSleepMode {
97
+ pwr : self ,
73
98
scb,
74
99
}
75
100
}
@@ -150,18 +175,64 @@ pub trait PowerMode {
150
175
///
151
176
/// Please note that entering Sleep mode may change the SCB configuration.
152
177
pub struct SleepMode < ' r > {
178
+ pwr : & ' r mut pac:: PWR ,
153
179
scb : & ' r mut SCB ,
154
180
}
155
181
156
182
impl PowerMode for SleepMode < ' _ > {
157
183
fn enter ( & mut self ) {
184
+ #[ cfg( feature = "stm32l0x1" ) ]
185
+ self . pwr . cr . modify ( |_, w| w. lpsdsr ( ) . main_mode ( ) ) ;
186
+ #[ cfg( any( feature = "stm32l0x2" , feature = "stm32l0x3" ) ) ]
187
+ self . pwr . cr . modify ( |_, w| w. lpds ( ) . clear_bit ( ) ) ;
188
+
158
189
self . scb . clear_sleepdeep ( ) ;
190
+
159
191
asm:: dsb ( ) ;
160
192
asm:: wfi ( ) ;
161
193
}
162
194
}
163
195
164
196
197
+ /// Low-power sleep mode
198
+ ///
199
+ /// You can get an instance of this struct by calling
200
+ /// [`PWR::low_power_sleep_mode`].
201
+ ///
202
+ /// The `PowerMode` implementation of this type will block until something wakes
203
+ /// the microcontroller up again. Please make sure to configure an interrupt, or
204
+ /// it could block forever.
205
+ ///
206
+ /// Please note that entering low-power sleep mode may change the SCB
207
+ /// configuration.
208
+ pub struct LowPowerSleepMode < ' r > {
209
+ pwr : & ' r mut PWR ,
210
+ scb : & ' r mut SCB ,
211
+ }
212
+
213
+ impl PowerMode for LowPowerSleepMode < ' _ > {
214
+ fn enter ( & mut self ) {
215
+ // Switch Vcore to range 2. This is required to enter low-power sleep
216
+ // mode, according to the reference manual, section 6.3.8.
217
+ let old_vcore = self . pwr . get_vcore_range ( ) ;
218
+ self . pwr . switch_vcore_range ( VcoreRange :: Range2 ) ;
219
+
220
+ #[ cfg( feature = "stm32l0x1" ) ]
221
+ self . pwr . 0 . cr . modify ( |_, w| w. lpsdsr ( ) . low_power_mode ( ) ) ;
222
+ #[ cfg( any( feature = "stm32l0x2" , feature = "stm32l0x3" ) ) ]
223
+ self . pwr . 0 . cr . modify ( |_, w| w. lpds ( ) . set_bit ( ) ) ;
224
+
225
+ self . scb . clear_sleepdeep ( ) ;
226
+
227
+ asm:: dsb ( ) ;
228
+ asm:: wfi ( ) ;
229
+
230
+ // Switch back to previous voltage range.
231
+ self . pwr . switch_vcore_range ( old_vcore) ;
232
+ }
233
+ }
234
+
235
+
165
236
/// Stop mode
166
237
///
167
238
/// You can get an instance of this struct by calling [`PWR::stop_mode`].
0 commit comments