@@ -71,6 +71,44 @@ impl<USB: UsbPeripheral> UsbBus<USB> {
7171 regs. cntr . modify ( |_, w| w. pdwn ( ) . bit ( pdwn) ) ;
7272 } ) ;
7373 }
74+
75+ /// Enter suspend low-power mode
76+ ///
77+ /// This should be used when in suspend mode if low-power mode needs to be entered during
78+ /// suspend (bus-powered device). Application should call this when it is ready to decrease
79+ /// power consumption to meet power consumption requirements of the USB suspend condition
80+ /// (e.g. disable system clocks or reduce their frequency). When wake up event is received
81+ /// low power mode will be automatically disabled.
82+ ///
83+ /// Will not enter low-power mode if not in suspend state. Returns `true` if entered.
84+ pub fn suspend_low_power_mode ( & self ) -> bool {
85+ interrupt:: free ( |cs| {
86+ let regs = self . regs . borrow ( cs) ;
87+ if regs. cntr . read ( ) . fsusp ( ) . is_suspend ( ) {
88+ regs. cntr . modify ( |_, w| w. lpmode ( ) . set_bit ( ) ) ;
89+ true
90+ } else {
91+ false
92+ }
93+ } )
94+ }
95+
96+ /// Set/clear remote wakeup bit
97+ ///
98+ /// Allows to modify CNTR.RESUME bit from device to perform remote wake up from suspend
99+ /// (e.g. on keyboard/mouse input). To perform remote wake up: when a condition is met
100+ /// during suspend mode, use this method with `true` to set the RESUME bit. Then, after
101+ /// waiting between 1-15 ms (see reference manual) call it again with `false` to clear
102+ /// the bit.
103+ ///
104+ /// This method will not set the bit if device is not suspended because performing remote
105+ /// wake up in other mode is invalid and host will most likely disable such a device.
106+ pub fn remote_wakeup ( & self , resume : bool ) {
107+ interrupt:: free ( |cs| {
108+ self . regs . borrow ( cs)
109+ . cntr . modify ( |r, w| w. resume ( ) . bit ( resume && r. fsusp ( ) . is_suspend ( ) ) ) ;
110+ } )
111+ }
74112}
75113
76114impl < USB : UsbPeripheral > usb_device:: bus:: UsbBus for UsbBus < USB > {
@@ -218,10 +256,7 @@ impl<USB: UsbPeripheral> usb_device::bus::UsbBus for UsbBus<USB> {
218256
219257 if v. ctr_tx ( ) . bit_is_set ( ) {
220258 ep_in_complete |= bit;
221-
222- interrupt:: free ( |cs| {
223- ep. clear_ctr_tx ( cs) ;
224- } ) ;
259+ ep. clear_ctr_tx ( cs) ;
225260 }
226261
227262 bit <<= 1 ;
@@ -288,7 +323,7 @@ impl<USB: UsbPeripheral> usb_device::bus::UsbBus for UsbBus<USB> {
288323 self . regs
289324 . borrow ( cs)
290325 . cntr
291- . modify ( |_, w| w. fsusp ( ) . set_bit ( ) . lpmode ( ) . set_bit ( ) ) ;
326+ . modify ( |_, w| w. fsusp ( ) . set_bit ( ) ) ;
292327 } ) ;
293328 }
294329
0 commit comments