1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
11 * Revisions copyright (C) 2005 by Gerald Van Baren
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
32 #include "mp3_playback.h"
34 #include "powermgmt.h"
35 #include "backlight.h"
42 #ifdef HAVE_LCD_BITMAP
46 #ifdef HAVE_REMOTE_LCD
47 #include "lcd-remote.h"
49 #if (CONFIG_PLATFORM & PLATFORM_HOSTED)
53 #if (defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(COWON_D2)) \
54 && !defined (SIMULATOR)
59 int last_sent_battery_level
= 100;
60 /* battery level (0-100%) */
61 int battery_percent
= -1;
62 void send_battery_level_event(void);
63 static void set_sleep_timer(int seconds
);
65 static bool sleeptimer_active
= false;
66 static long sleeptimer_endtick
;
67 /* Whether an active sleep timer should be restarted when a key is pressed */
68 static bool sleeptimer_key_restarts
= false;
69 /* The number of seconds the sleep timer was last set to */
70 static unsigned int sleeptimer_duration
= 0;
73 /* State of the charger input as seen by the power thread */
74 enum charger_input_state_type charger_input_state
;
75 /* Power inputs as seen by the power thread */
76 unsigned int power_thread_inputs
;
77 #if CONFIG_CHARGING >= CHARGING_MONITOR
78 /* Charging state (mode) as seen by the power thread */
79 enum charge_state_type charge_state
= DISCHARGING
;
81 #endif /* CONFIG_CHARGING */
83 static int shutdown_timeout
= 0;
85 void handle_auto_poweroff(void);
86 static int poweroff_timeout
= 0;
87 static long last_event_tick
= 0;
89 #if (CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE) == PERCENTAGE_MEASURE
90 int _battery_voltage(void) { return -1; }
92 const unsigned short percent_to_volt_discharge
[BATTERY_TYPES_COUNT
][11];
93 const unsigned short percent_to_volt_charge
[11];
95 #elif (CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE) == VOLTAGE_MEASURE
96 int _battery_level(void) { return -1; }
98 * Average battery voltage and charger voltage, filtered via a digital
99 * exponential filter (aka. exponential moving average, scaled):
100 * avgbat = y[n] = (N-1)/N*y[n-1] + x[n]. battery_millivolts = y[n] / N.
102 static unsigned int avgbat
;
103 /* filtered battery voltage, millivolts */
104 static unsigned int battery_millivolts
;
105 #elif (CONFIG_BATTERY_MEASURE == 0)
106 int _battery_voltage(void) { return -1; }
107 int _battery_level(void) { return -1; }
109 const unsigned short percent_to_volt_discharge
[BATTERY_TYPES_COUNT
][11];
110 const unsigned short percent_to_volt_charge
[11];
113 #if !(CONFIG_BATTERY_MEASURE & TIME_MEASURE)
114 static int powermgmt_est_runningtime_min
;
115 int _battery_time(void) { return powermgmt_est_runningtime_min
; }
118 /* default value, mAh */
119 static int battery_capacity
= BATTERY_CAPACITY_DEFAULT
;
121 #if BATTERY_TYPES_COUNT > 1
122 static int battery_type
= 0;
124 #define battery_type 0
127 /* Power history: power_history[0] is the newest sample */
128 unsigned short power_history
[POWER_HISTORY_LEN
] = {0};
130 #if CONFIG_CPU == JZ4732 /* FIXME! */ || (CONFIG_PLATFORM & PLATFORM_HOSTED)
131 static char power_stack
[DEFAULT_STACK_SIZE
+ POWERMGMT_DEBUG_STACK
];
133 static char power_stack
[DEFAULT_STACK_SIZE
/2 + POWERMGMT_DEBUG_STACK
];
135 static const char power_thread_name
[] = "power";
138 static int voltage_to_battery_level(int battery_millivolts
);
139 static void battery_status_update(void);
141 #ifdef CURRENT_NORMAL /*only used if we have run current*/
142 static int runcurrent(void);
145 void battery_read_info(int *voltage
, int *level
)
147 int millivolts
= _battery_voltage();
151 *voltage
= millivolts
;
154 percent
= voltage_to_battery_level(millivolts
);
156 percent
= _battery_level();
161 #if BATTERY_TYPES_COUNT > 1
162 void set_battery_type(int type
)
164 if (type
!= battery_type
) {
165 if ((unsigned)type
>= BATTERY_TYPES_COUNT
)
169 battery_status_update(); /* recalculate the battery status */
174 #ifdef BATTERY_CAPACITY_MIN
175 void set_battery_capacity(int capacity
)
177 if (capacity
> BATTERY_CAPACITY_MAX
)
178 capacity
= BATTERY_CAPACITY_MAX
;
179 if (capacity
< BATTERY_CAPACITY_MIN
)
180 capacity
= BATTERY_CAPACITY_MIN
;
182 battery_capacity
= capacity
;
184 battery_status_update(); /* recalculate the battery status */
188 int get_battery_capacity(void)
190 return battery_capacity
;
193 int battery_time(void)
195 #if ((CONFIG_BATTERY_MEASURE & TIME_MEASURE) == 0)
197 #ifndef CURRENT_NORMAL /* no estimation without current */
200 if (battery_capacity
<= 0) /* nor without capacity */
204 return _battery_time();
207 /* Returns battery level in percent */
208 int battery_level(void)
210 #ifdef HAVE_BATTERY_SWITCH
211 if ((power_input_status() & POWER_INPUT_BATTERY
) == 0)
214 return battery_percent
;
217 /* Tells if the battery level is safe for disk writes */
218 bool battery_level_safe(void)
220 #if defined(NO_LOW_BATTERY_SHUTDOWN)
222 #elif (CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE)
223 return (battery_percent
> 0);
224 #elif defined(HAVE_BATTERY_SWITCH)
225 /* Cannot rely upon the battery reading to be valid and the
226 * device could be powered externally. */
227 return input_millivolts() > battery_level_dangerous
[battery_type
];
229 return battery_millivolts
> battery_level_dangerous
[battery_type
];
233 /* look into the percent_to_volt_* table and get a realistic battery level */
234 static int voltage_to_percent(int voltage
, const short* table
)
236 if (voltage
<= table
[0]) {
239 else if (voltage
>= table
[10]) {
243 /* search nearest value */
246 while (i
< 10 && table
[i
+1] < voltage
)
249 /* interpolate linear between the smaller and greater value */
250 /* Tens digit, 10% per entry, ones digit: interpolated */
251 return i
*10 + (voltage
- table
[i
])*10 / (table
[i
+1] - table
[i
]);
255 /* update battery level and estimated runtime, called once per minute or
256 * when battery capacity / type settings are changed */
257 static int voltage_to_battery_level(int battery_millivolts
)
261 if (battery_millivolts
< 0)
264 #if CONFIG_CHARGING >= CHARGING_MONITOR
265 if (charging_state()) {
266 /* battery level is defined to be < 100% until charging is finished */
267 level
= voltage_to_percent(battery_millivolts
,
268 percent_to_volt_charge
);
273 #endif /* CONFIG_CHARGING >= CHARGING_MONITOR */
275 /* DISCHARGING or error state */
276 level
= voltage_to_percent(battery_millivolts
,
277 percent_to_volt_discharge
[battery_type
]);
283 static void battery_status_update(void)
285 int millivolt
= battery_voltage();
286 int level
= _battery_level();
289 level
= voltage_to_battery_level(millivolt
);
291 #ifdef CURRENT_NORMAL /*don't try to estimate run or charge
292 time without normal current defined*/
293 /* calculate estimated remaining running time */
294 #if CONFIG_CHARGING >= CHARGING_MONITOR
295 if (charging_state()) {
296 /* charging: remaining charging time */
297 powermgmt_est_runningtime_min
= (100 - level
)*battery_capacity
*60
298 / 100 / (CURRENT_MAX_CHG
- runcurrent());
303 /* discharging: remaining running time */
304 if (level
> 0 && (millivolt
> percent_to_volt_discharge
[battery_type
][0]
306 /* linear extrapolation */
307 powermgmt_est_runningtime_min
= (level
+ battery_percent
)*60
308 * battery_capacity
/ 200 / runcurrent();
310 if (0 > powermgmt_est_runningtime_min
) {
311 powermgmt_est_runningtime_min
= 0;
315 battery_percent
= level
;
316 send_battery_level_event();
319 #ifdef CURRENT_NORMAL /*check that we have a current defined in a config file*/
322 * Estimate how much current we are drawing just to run.
324 static int runcurrent(void)
326 int current
= CURRENT_NORMAL
;
330 #ifdef HAVE_USB_POWER
331 #if (CURRENT_USB < CURRENT_NORMAL)
338 current
= CURRENT_USB
;
341 #if defined(HAVE_BACKLIGHT)
342 if (backlight_get_current_timeout() == 0) /* LED always on */
343 current
+= CURRENT_BACKLIGHT
;
346 #if defined(HAVE_RECORDING) && defined(CURRENT_RECORD)
347 if (audio_status() & AUDIO_STATUS_RECORD
)
348 current
+= CURRENT_RECORD
;
351 #ifdef HAVE_SPDIF_POWER
353 current
+= CURRENT_SPDIF_OUT
;
356 #ifdef HAVE_REMOTE_LCD
358 current
+= CURRENT_REMOTE
;
361 #if defined(HAVE_ATA_POWER_OFF) && defined(CURRENT_ATA)
363 current
+= CURRENT_ATA
;
366 #endif /* BOOTLOADER */
371 #endif /* CURRENT_NORMAL */
373 /* Check to see whether or not we've received an alarm in the last second */
374 #ifdef HAVE_RTC_ALARM
375 static void power_thread_rtc_process(void)
377 if (rtc_check_alarm_flag())
378 rtc_enable_alarm(false);
382 /* switch off unit if battery level is too low for reliable operation */
383 bool query_force_shutdown(void)
385 #if defined(NO_LOW_BATTERY_SHUTDOWN)
387 #elif CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE
388 return battery_percent
== 0;
389 #elif defined(HAVE_BATTERY_SWITCH)
390 /* Cannot rely upon the battery reading to be valid and the
391 * device could be powered externally. */
392 return input_millivolts() < battery_level_shutoff
[battery_type
];
394 return battery_millivolts
< battery_level_shutoff
[battery_type
];
398 #if defined(HAVE_BATTERY_SWITCH) || defined(HAVE_RESET_BATTERY_FILTER)
400 * Reset the battery voltage filter to a new value and update the
403 void reset_battery_filter(int millivolts
)
405 avgbat
= millivolts
* BATT_AVE_SAMPLES
;
406 battery_millivolts
= millivolts
;
407 battery_status_update();
409 #endif /* HAVE_BATTERY_SWITCH */
411 /** Generic charging algorithms for common charging types **/
412 #if CONFIG_CHARGING == 0 || CONFIG_CHARGING == CHARGING_SIMPLE
413 static inline void powermgmt_init_target(void)
418 static inline void charging_algorithm_step(void)
423 static inline void charging_algorithm_close(void)
427 #elif CONFIG_CHARGING == CHARGING_MONITOR
429 * Monitor CHARGING/DISCHARGING state.
431 static inline void powermgmt_init_target(void)
436 static inline void charging_algorithm_step(void)
438 switch (charger_input_state
)
440 case CHARGER_PLUGGED
:
442 if (charging_state()) {
443 charge_state
= CHARGING
;
447 case CHARGER_UNPLUGGED
:
449 charge_state
= DISCHARGING
;
454 static inline void charging_algorithm_close(void)
458 #endif /* CONFIG_CHARGING == * */
461 /* Shortcut function calls - compatibility, simplicity. */
463 /* Returns true if any power input is capable of charging. */
464 bool charger_inserted(void)
466 return power_thread_inputs
& POWER_INPUT_CHARGER
;
469 /* Returns true if any power input is connected - charging-capable
471 bool power_input_present(void)
473 return power_thread_inputs
& POWER_INPUT
;
477 * Detect charger inserted. Return true if the state is transistional.
479 static inline bool detect_charger(unsigned int pwr
)
482 * Detect charger plugged/unplugged transitions. On a plugged or
483 * unplugged event, we return immediately, run once through the main
484 * loop (including the subroutines), and end up back here where we
485 * transition to the appropriate steady state charger on/off state.
487 if (pwr
& POWER_INPUT_CHARGER
) {
488 switch (charger_input_state
)
491 case CHARGER_UNPLUGGED
:
492 charger_input_state
= CHARGER_PLUGGED
;
495 case CHARGER_PLUGGED
:
496 queue_broadcast(SYS_CHARGER_CONNECTED
, 0);
497 last_sent_battery_level
= 0;
498 charger_input_state
= CHARGER
;
506 else { /* charger not inserted */
507 switch (charger_input_state
)
513 case CHARGER_UNPLUGGED
:
514 queue_broadcast(SYS_CHARGER_DISCONNECTED
, 0);
515 last_sent_battery_level
= 100;
516 charger_input_state
= NO_CHARGER
;
519 case CHARGER_PLUGGED
:
521 charger_input_state
= CHARGER_UNPLUGGED
;
526 /* Transitional state */
529 #endif /* CONFIG_CHARGING */
532 #if CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE
533 /* Returns filtered battery voltage [millivolts] */
534 int battery_voltage(void)
536 return battery_millivolts
;
539 static void average_init(void)
541 /* initialize the voltages for the exponential filter */
542 avgbat
= _battery_voltage() + 15;
544 #ifdef HAVE_DISK_STORAGE /* this adjustment is only needed for HD based */
545 /* The battery voltage is usually a little lower directly after
546 turning on, because the disk was used heavily. Raise it by 5% */
548 if (!charger_inserted()) /* only if charger not connected */
551 avgbat
+= (percent_to_volt_discharge
[battery_type
][6] -
552 percent_to_volt_discharge
[battery_type
][5]) / 2;
554 #endif /* HAVE_DISK_STORAGE */
556 avgbat
= avgbat
* BATT_AVE_SAMPLES
;
557 battery_millivolts
= power_history
[0] = avgbat
/ BATT_AVE_SAMPLES
;
560 static void average_step(void)
562 avgbat
+= _battery_voltage() - avgbat
/ BATT_AVE_SAMPLES
;
564 * battery_millivolts is the millivolt-scaled filtered battery value.
566 battery_millivolts
= avgbat
/ BATT_AVE_SAMPLES
;
569 static void average_step_low(void)
571 battery_millivolts
= (_battery_voltage() + battery_millivolts
+ 1) / 2;
572 avgbat
+= battery_millivolts
- avgbat
/ BATT_AVE_SAMPLES
;
575 static void init_battery_percent(void)
578 if (charger_inserted()) {
579 battery_percent
= voltage_to_percent(battery_millivolts
,
580 percent_to_volt_charge
);
585 battery_percent
= voltage_to_percent(battery_millivolts
,
586 percent_to_volt_discharge
[battery_type
]);
587 battery_percent
+= battery_percent
< 100;
592 static int power_hist_item(void)
594 return battery_millivolts
;
596 #define power_history_unit() battery_millivolts
599 int battery_voltage(void)
604 static void average_init(void) {}
605 static void average_step(void) {}
606 static void average_step_low(void) {}
607 static void init_battery_percent(void)
609 battery_percent
= _battery_level();
612 static int power_hist_item(void)
614 return battery_percent
;
618 static void collect_power_history(void)
620 /* rotate the power history */
621 memmove(&power_history
[1], &power_history
[0],
622 sizeof(power_history
) - sizeof(power_history
[0]));
623 power_history
[0] = power_hist_item();
627 * Monitor the presence of a charger and perform critical frequent steps
628 * such as running the battery voltage filter.
630 static inline void power_thread_step(void)
632 /* If the power off timeout expires, the main thread has failed
633 to shut down the system, and we need to force a power off */
634 if (shutdown_timeout
) {
635 shutdown_timeout
-= POWER_THREAD_STEP_TICKS
;
637 if (shutdown_timeout
<= 0)
641 #ifdef HAVE_RTC_ALARM
642 power_thread_rtc_process();
646 * Do a digital exponential filter. We don't sample the battery if
647 * the disk is spinning unless we are in USB mode (the disk will most
648 * likely always be spinning in USB mode) or charging.
650 if (!storage_disk_is_active() || usb_inserted()
651 #if CONFIG_CHARGING >= CHARGING_MONITOR
652 || charger_input_state
== CHARGER
656 /* update battery status every time an update is available */
657 battery_status_update();
659 else if (battery_percent
< 8) {
661 /* update battery status every time an update is available */
662 battery_status_update();
665 * If battery is low, observe voltage during disk activity.
666 * Shut down if voltage drops below shutoff level and we are not
667 * using NiMH or Alkaline batteries.
669 if (!shutdown_timeout
&& query_force_shutdown()) {
673 } /* power_thread_step */
675 static void power_thread(void)
677 long next_power_hist
;
679 /* Delay reading the first battery level */
681 while (_battery_voltage() > 4200) /* gives false readings initially */
688 /* Initialize power input status before calling other routines. */
689 power_thread_inputs
= power_input_status();
692 /* initialize voltage averaging (if available) */
694 /* get initial battery level value (in %) */
695 init_battery_percent();
696 /* get some initial data for the power curve */
697 collect_power_history();
698 /* call target specific init now */
699 powermgmt_init_target();
701 next_power_hist
= current_tick
+ HZ
*60;
706 unsigned int pwr
= power_input_status();
707 #ifdef HAVE_BATTERY_SWITCH
708 if ((pwr
^ power_thread_inputs
) & POWER_INPUT_BATTERY
) {
710 reset_battery_filter(_battery_voltage());
713 power_thread_inputs
= pwr
;
715 if (!detect_charger(pwr
))
716 #endif /* CONFIG_CHARGING */
719 sleep(POWER_THREAD_STEP_TICKS
);
721 /* Do common power tasks */
725 /* Perform target tasks */
726 charging_algorithm_step();
728 /* check if some idle or sleep timer wears off */
729 handle_auto_poweroff();
731 if (TIME_AFTER(current_tick
, next_power_hist
)) {
732 /* increment to ensure there is a record for every minute
733 * rather than go forward from the current tick */
734 next_power_hist
+= HZ
*60;
735 collect_power_history();
740 void powermgmt_init(void)
742 create_thread(power_thread
, power_stack
, sizeof(power_stack
), 0,
743 power_thread_name
IF_PRIO(, PRIORITY_SYSTEM
)
747 /* Various hardware housekeeping tasks relating to shutting down the player */
748 void shutdown_hw(void)
750 charging_algorithm_close();
753 if (battery_level_safe()) { /* do not save on critical battery */
754 #ifdef HAVE_LCD_BITMAP
758 /* Commit pending writes if needed. Even though we don't do write caching,
759 things like flash translation layers may need this to commit scattered
760 pages to there final locations. So far only used for iPod Nano 2G. */
761 #ifdef HAVE_STORAGE_FLUSH
765 if (storage_disk_is_active())
769 #if CONFIG_CODEC == SWCODEC
775 /* If HD is still active we try to wait for spindown, otherwise the
776 shutdown_timeout in power_thread_step will force a power off */
777 while (storage_disk_is_active())
780 #ifndef HAVE_LCD_COLOR
783 #ifdef HAVE_REMOTE_LCD
784 lcd_remote_set_contrast(0);
786 #ifdef HAVE_LCD_SHUTDOWN
790 /* Small delay to make sure all HW gets time to flush. Especially
791 eeprom chips are quite slow and might be still writing the last
797 void set_poweroff_timeout(int timeout
)
799 poweroff_timeout
= timeout
;
802 void reset_poweroff_timer(void)
804 last_event_tick
= current_tick
;
805 if (sleeptimer_active
&& sleeptimer_key_restarts
)
806 set_sleep_timer(sleeptimer_duration
);
809 void sys_poweroff(void)
812 logf("sys_poweroff()");
813 /* If the main thread fails to shut down the system, we will force a
814 power off after an 20 second timeout - 28 seconds if recording */
815 if (shutdown_timeout
== 0) {
816 #if (defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(COWON_D2)) && !defined(SIMULATOR)
817 pcf50606_reset_timeout(); /* Reset timer on first attempt only */
819 #ifdef HAVE_RECORDING
820 if (audio_status() & AUDIO_STATUS_RECORD
)
821 shutdown_timeout
+= HZ
*8;
824 /* The FTL alone may take half a minute to shut down cleanly. */
825 shutdown_timeout
+= HZ
*60;
827 shutdown_timeout
+= HZ
*20;
831 queue_broadcast(SYS_POWEROFF
, 0);
832 #endif /* BOOTLOADER */
835 void cancel_shutdown(void)
837 logf("cancel_shutdown()");
839 #if (defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(COWON_D2)) && !defined(SIMULATOR)
840 /* TODO: Move some things to target/ tree */
841 if (shutdown_timeout
)
842 pcf50606_reset_timeout();
845 shutdown_timeout
= 0;
848 /* Send system battery level update events on reaching certain significant
849 levels. This must be called after battery_percent has been updated. */
850 void send_battery_level_event(void)
852 static const int levels
[] = { 5, 15, 30, 50, 0 };
853 const int *level
= levels
;
857 if (battery_percent
<= *level
&& last_sent_battery_level
> *level
) {
858 last_sent_battery_level
= *level
;
859 queue_broadcast(SYS_BATTERY_UPDATE
, last_sent_battery_level
);
867 void set_sleeptimer_duration(int minutes
)
869 set_sleep_timer(minutes
* 60);
872 static void set_sleep_timer(int seconds
)
875 sleeptimer_active
= true;
876 sleeptimer_endtick
= current_tick
+ seconds
* HZ
;
879 sleeptimer_active
= false;
880 sleeptimer_endtick
= 0;
882 sleeptimer_duration
= seconds
;
885 int get_sleep_timer(void)
887 if (sleeptimer_active
&& (sleeptimer_endtick
>= current_tick
))
888 return (sleeptimer_endtick
- current_tick
) / HZ
;
893 void set_keypress_restarts_sleep_timer(bool enable
)
895 sleeptimer_key_restarts
= enable
;
899 static void handle_sleep_timer(void)
901 if (!sleeptimer_active
)
904 /* Handle sleeptimer */
905 if (TIME_AFTER(current_tick
, sleeptimer_endtick
)) {
907 #if CONFIG_CHARGING && !defined(HAVE_POWEROFF_WHILE_CHARGING)
908 || charger_input_state
!= NO_CHARGER
911 DEBUGF("Sleep timer timeout. Stopping...\n");
914 backlight_off(); /* Nighty, nighty... */
917 DEBUGF("Sleep timer timeout. Shutting off...\n");
922 #endif /* BOOTLOADER */
925 * We shut off in the following cases:
926 * 1) The unit is idle, not playing music
927 * 2) The unit is playing music, but is paused
928 * 3) The battery level has reached shutdown limit
930 * We do not shut off in the following cases:
931 * 1) The USB is connected
932 * 2) The charger is connected
933 * 3) We are recording, or recording with pause
934 * 4) The radio is playing
936 void handle_auto_poweroff(void)
939 long timeout
= poweroff_timeout
*60*HZ
;
940 int audio_stat
= audio_status();
941 long tick
= current_tick
;
944 * Inhibit shutdown as long as the charger is plugged in. If it is
945 * unplugged, wait for a timeout period and then shut down.
947 if (audio_stat
== AUDIO_STATUS_PLAY
949 || charger_input_state
== CHARGER
952 last_event_tick
= current_tick
;
955 if (!shutdown_timeout
&& query_force_shutdown()) {
962 !(get_radio_status() & FMRADIO_PLAYING
) &&
966 (audio_stat
== (AUDIO_STATUS_PLAY
| AUDIO_STATUS_PAUSE
) &&
967 !sleeptimer_active
))) {
969 if (TIME_AFTER(tick
, last_event_tick
+ timeout
)
970 #if !(CONFIG_PLATFORM & PLATFORM_HOSTED)
971 && TIME_AFTER(tick
, storage_last_disk_activity() + timeout
)
977 handle_sleep_timer();