@@ -33,6 +33,10 @@ const SLEEP_MODE: SleepMode = SleepMode::Fading;
3333
3434const STARTUP_ANIMATION : bool = true ;
3535
36+ /// Go to sleep after 60s awake
37+ const SLEEP_TIMEOUT : u64 = 60_000_000 ;
38+
39+ /// List maximum current as 500mA in the USB descriptor
3640const MAX_CURRENT : usize = 500 ;
3741
3842/// Maximum brightness out of 255
@@ -232,8 +236,9 @@ fn main() -> ! {
232236 fill_grid_pixels ( & state, & mut matrix) ;
233237
234238 let timer = Timer :: new ( pac. TIMER , & mut pac. RESETS ) ;
235- let mut prev_timer = timer. get_counter ( ) . ticks ( ) ;
239+ let mut animation_timer = timer. get_counter ( ) . ticks ( ) ;
236240 let mut game_timer = timer. get_counter ( ) . ticks ( ) ;
241+ let mut sleep_timer = timer. get_counter ( ) . ticks ( ) ;
237242
238243 let mut startup_percentage = Some ( 0 ) ;
239244 if !STARTUP_ANIMATION {
@@ -254,27 +259,58 @@ fn main() -> ! {
254259 }
255260
256261 let mut usb_initialized = false ;
257- let mut usb_suspended = true ;
262+ let mut usb_suspended = false ;
263+ let mut last_usb_suspended = usb_suspended;
264+ let mut sleeping = false ;
265+ let mut last_host_sleep = sleep. is_low ( ) . unwrap ( ) ;
258266
259267 loop {
260268 if sleep_present {
261269 // Go to sleep if the host is sleeping
262- // Or if USB is suspended. Only if it was previously initialized,
263- // since the OS puts the device into suspend before it's fully
264- // initialized for the first time. But we don't want to show the
265- // sleep animation during startup.
266- let host_sleeping = sleep. is_low ( ) . unwrap ( ) || ( usb_suspended && usb_initialized) ;
267- handle_sleep (
268- host_sleeping,
269- & mut state,
270- & mut matrix,
271- & mut delay,
272- & mut led_enable,
273- ) ;
270+ let host_sleeping = sleep. is_low ( ) . unwrap ( ) ;
271+ let host_sleep_changed = host_sleeping != last_host_sleep;
272+ // Change sleep state either if SLEEP# has changed
273+ // Or if it currently sleeping. Don't change if not sleeping
274+ // because then sleep is controlled by timing or by API.
275+ if host_sleep_changed || host_sleeping {
276+ sleeping = host_sleeping;
277+ }
278+ last_host_sleep = host_sleeping;
274279 }
275280
281+ // Change sleep state either if SLEEP# has changed
282+ // Or if it currently sleeping. Don't change if not sleeping
283+ // because then sleep is controlled by timing or by API.
284+ let usb_suspended_changed = usb_suspended != last_usb_suspended;
285+ // Only if USB was previously initialized,
286+ // since the OS puts the device into suspend before it's fully
287+ // initialized for the first time. But we don't want to show the
288+ // sleep animation during startup.
289+ if usb_initialized && ( usb_suspended_changed || usb_suspended) {
290+ sleeping = usb_suspended;
291+ }
292+ last_usb_suspended = usb_suspended;
293+
294+ // Go to sleep after the timer has run out
295+ if timer. get_counter ( ) . ticks ( ) > sleep_timer + SLEEP_TIMEOUT {
296+ sleeping = true ;
297+ }
298+ // Constantly resetting timer during sleep is same as reset it once on waking up.
299+ // This means the timer ends up counting the time spent awake.
300+ if sleeping {
301+ sleep_timer = timer. get_counter ( ) . ticks ( ) ;
302+ }
303+
304+ handle_sleep (
305+ sleeping,
306+ & mut state,
307+ & mut matrix,
308+ & mut delay,
309+ & mut led_enable,
310+ ) ;
311+
276312 // Handle period display updates. Don't do it too often
277- let render_again = timer. get_counter ( ) . ticks ( ) > prev_timer + state. animation_period ;
313+ let render_again = timer. get_counter ( ) . ticks ( ) > animation_timer + state. animation_period ;
278314 if matches ! ( state. sleeping, SleepState :: Awake ) && render_again {
279315 // On startup slowly turn the screen on - it's a pretty effect :)
280316 match startup_percentage {
@@ -291,7 +327,7 @@ fn main() -> ! {
291327 state. grid . 0 [ x] . rotate_right ( 1 ) ;
292328 }
293329 }
294- prev_timer = timer. get_counter ( ) . ticks ( ) ;
330+ animation_timer = timer. get_counter ( ) . ticks ( ) ;
295331 }
296332
297333 // Check for new data
@@ -325,28 +361,43 @@ fn main() -> ! {
325361 Ok ( count) => {
326362 let random = get_random_byte ( & rosc) ;
327363 match ( parse_command ( count, & buf) , & state. sleeping ) {
328- ( Some ( Command :: Sleep ( go_sleeping) ) , _) => {
364+ // Handle bootloader command without any delay
365+ // No need, it'll reset the device anyways
366+ ( Some ( c @ Command :: BootloaderReset ) , _) => {
367+ handle_command ( & c, & mut state, & mut matrix, random) ;
368+ }
369+ ( Some ( command) , _) => {
370+ if let Command :: Sleep ( go_sleeping) = command {
371+ sleeping = go_sleeping;
372+ } else {
373+ // If already sleeping, wake up.
374+ // This means every command will wake the device up.
375+ // Much more convenient than having to send the wakeup commmand.
376+ sleeping = false ;
377+ }
378+ // Make sure sleep animation only goes up to newly set brightness,
379+ // if setting the brightness causes wakeup
380+ if let SleepState :: Sleeping ( ( ref grid, _) ) = state. sleeping {
381+ if let Command :: SetBrightness ( new_brightness) = command {
382+ state. sleeping =
383+ SleepState :: Sleeping ( ( grid. clone ( ) , new_brightness) ) ;
384+ }
385+ }
329386 handle_sleep (
330- go_sleeping ,
387+ sleeping ,
331388 & mut state,
332389 & mut matrix,
333390 & mut delay,
334391 & mut led_enable,
335392 ) ;
336- }
337- ( Some ( c @ Command :: BootloaderReset ) , _)
338- | ( Some ( c @ Command :: IsSleeping ) , _) => {
339- if let Some ( response) =
340- handle_command ( & c, & mut state, & mut matrix, random)
341- {
342- let _ = serial. write ( & response) ;
343- } ;
344- }
345- ( Some ( command) , SleepState :: Awake ) => {
393+
346394 // If there's a very early command, cancel the startup animation
347395 startup_percentage = None ;
348396
349- // While sleeping no command is handled, except waking up
397+ // Reset sleep timer when interacting with the device
398+ // Very easy way to keep the device from going to sleep
399+ sleep_timer = timer. get_counter ( ) . ticks ( ) ;
400+
350401 if let Some ( response) =
351402 handle_command ( & command, & mut state, & mut matrix, random)
352403 {
@@ -361,9 +412,11 @@ fn main() -> ! {
361412 buf[ 0 ] , buf[ 1 ] , buf[ 2 ] , buf[ 3 ]
362413 )
363414 . unwrap ( ) ;
415+ // let _ = serial.write(text.as_bytes());
416+
364417 fill_grid_pixels ( & state, & mut matrix) ;
365418 }
366- _ => { }
419+ ( None , _ ) => { }
367420 }
368421 }
369422 }
@@ -435,6 +488,7 @@ fn get_random_byte(rosc: &RingOscillator<Enabled>) -> u8 {
435488 byte
436489}
437490
491+ // Will do nothing if already in the right state
438492fn handle_sleep (
439493 go_sleeping : bool ,
440494 state : & mut LedmatrixState ,
0 commit comments