diff --git a/apps/playback.c b/apps/playback.c index f4274a8f02..c0558ed737 100644 --- a/apps/playback.c +++ b/apps/playback.c @@ -2781,6 +2781,7 @@ static void audio_fill_file_buffer( filling = false; } + ata_sleep(); } static void audio_rebuffer(void) diff --git a/apps/settings.c b/apps/settings.c index ec96cc760b..08e6376694 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -38,6 +38,7 @@ #include "talk.h" #include "string.h" #include "ata.h" +#include "ata_idle_notify.h" #include "fat.h" #include "power.h" #include "powermgmt.h" @@ -802,6 +803,11 @@ static void init_config_buffer( void ) config_block[3] = CONFIG_BLOCK_VERSION; } +bool flush_config_block_callback(void) +{ + ata_write_sectors(IF_MV2(0,) config_sector, 1, config_block); + return true; +} /* * save the config block buffer to disk or RTC RAM */ @@ -833,7 +839,7 @@ static int save_config_buffer( void ) #endif if (config_sector != 0) - ata_delayed_write( config_sector, config_block); + register_ata_idle_func(flush_config_block_callback); else return -1; diff --git a/firmware/ata_idle_notify.c b/firmware/ata_idle_notify.c index a0a56e958b..c51c3800ce 100644 --- a/firmware/ata_idle_notify.c +++ b/firmware/ata_idle_notify.c @@ -18,8 +18,10 @@ ****************************************************************************/ #include #include "system.h" +#include "ata.h" #include "ata_idle_notify.h" #include "logf.h" +#include "string.h" #if USING_ATA_CALLBACK static ata_idle_notify ata_idle_notify_funcs[MAX_ATA_CALLBACKS]; @@ -52,7 +54,7 @@ bool register_ata_idle_func(ata_idle_notify function) } #if USING_ATA_CALLBACK -void unregister_ata_idle_func(ata_idle_notify func) +void unregister_ata_idle_func(ata_idle_notify func, bool run) { int i; for (i=0; i + +#if 0 + NOTE: ata_idle_nofity usage notes.. + + 1) the callbacks are called in the ata thread, not main/your thread. + 2) Asyncronous callbacks (like the buffer refill) should be avoided. + If you must use an async callback, remember to check ata_is_active() before + accessing the disk, and nonot call any functions between that check and the + disk access which may cause a yield (lcd_update() does this!) + 3) Do not call cany yielding functions in the callback + 4) Do not call ata_sleep in the callbacks + 5) Dont Panic! +#endif + #define USING_ATA_CALLBACK !defined(SIMULATOR) \ && !defined(HAVE_FLASH_DISK) \ && !defined(HAVE_MMC) - + #define MAX_ATA_CALLBACKS 5 typedef bool (*ata_idle_notify)(void); extern bool register_ata_idle_func(ata_idle_notify function); #if USING_ATA_CALLBACK extern void ata_idle_notify_init(void); -extern void unregister_ata_idle_func(ata_idle_notify function); -extern bool call_ata_idle_notifys(void); +extern void unregister_ata_idle_func(ata_idle_notify function, bool run); +extern bool call_ata_idle_notifys(bool sleep_after); #else -#define unregister_ata_idle_func(f) +#define unregister_ata_idle_func(f,r) #define call_ata_idle_notifys() -#define ata_idle_notify_init() +#define ata_idle_notify_init(s) #endif #endif /* __ATACALLBACK_H__ */ diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c index f258502c2c..2ca176d072 100644 --- a/firmware/powermgmt.c +++ b/firmware/powermgmt.c @@ -1098,7 +1098,6 @@ void shutdown_hw(void) #ifdef HAVE_LCD_BITMAP glyph_cache_save(); #endif - ata_flush(); ata_spindown(1); while(ata_disk_is_active()) sleep(HZ/10);