1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 Björn Stenberg
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
23 #include "gcc_extensions.h"
34 #include "filetypes.h"
39 #include "powermgmt.h"
46 #include "mp3_playback.h"
49 #include "backlight.h"
51 #include "debug_menu.h"
59 #include "usb_screen.h"
72 #include "eeprom_settings.h"
73 #include "scrobbler.h"
76 #include "skin_engine/skin_engine.h"
77 #include "statusbar-skinned.h"
78 #include "bootchart.h"
79 #if defined(APPLICATION) && (CONFIG_PLATFORM & PLATFORM_ANDROID)
80 #include "notification.h"
83 #ifdef IPOD_ACCESSORY_PROTOCOL
87 #if (CONFIG_CODEC == SWCODEC)
91 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
92 #include "pcm_record.h"
96 #define SETTINGS_RESET BUTTON_REC
97 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
98 #define SETTINGS_RESET BUTTON_A
104 #if (CONFIG_STORAGE & STORAGE_MMC)
108 #ifdef HAVE_REMOTE_LCD
109 #include "lcd-remote.h"
112 #if CONFIG_USBOTG == USBOTG_ISP1362
116 #if CONFIG_USBOTG == USBOTG_M5636
120 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
121 #define MAIN_NORETURN_ATTR NORETURN_ATTR
123 /* gcc adds an implicit 'return 0;' at the end of main(), causing a warning
124 * with noreturn attribute */
125 #define MAIN_NORETURN_ATTR
128 #if (CONFIG_PLATFORM & (PLATFORM_SDL|PLATFORM_MAEMO))
129 #include "sim_tasks.h"
130 #include "system-sdl.h"
131 #define HAVE_ARGV_MAIN
132 /* Don't use SDL_main on windows -> no more stdio redirection */
138 /*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
140 static void init(void);
141 /* main(), and various functions called by main() and init() may be
142 * be INIT_ATTR. These functions must not be called after the final call
143 * to root_menu() at the end of main()
144 * see definition of INIT_ATTR in config.h */
145 #ifdef HAVE_ARGV_MAIN
146 int main(int argc
, char *argv
[]) INIT_ATTR MAIN_NORETURN_ATTR
;
147 int main(int argc
, char *argv
[])
149 sys_handle_argv(argc
, argv
);
151 int main(void) INIT_ATTR MAIN_NORETURN_ATTR
;
161 screens
[i
].clear_display();
164 #ifdef HAVE_LCD_BITMAP
168 /* Keep the order of this 3
169 * Must be done before any code uses the multi-screen API */
171 /* All threads should be created and public queues registered by now */
172 usb_start_monitoring();
177 char filename
[MAX_PATH
];
185 if(file_exists(file
)) /* no complaint if it doesn't exist */
187 plugin_load(file
, NULL
); /* start if it does */
190 #endif /* #ifdef AUTOROCK */
192 global_status
.last_volume_change
= 0;
193 /* no calls INIT_ATTR functions after this point anymore!
194 * see definition of INIT_ATTR in config.h */
199 static int init_dircache(bool preinit
) INIT_ATTR
;
200 static int init_dircache(bool preinit
)
209 if (!global_settings
.dircache
)
212 # ifdef HAVE_EEPROM_SETTINGS
213 if (firmware_settings
.initialized
&& firmware_settings
.disk_clean
216 result
= dircache_load();
220 firmware_settings
.disk_clean
= false;
221 if (global_status
.dircache_size
<= 0)
223 /* This will be in default language, settings are not
224 applied yet. Not really any easy way to fix that. */
225 splash(0, str(LANG_SCANNING_DISK
));
229 dircache_build(global_status
.dircache_size
);
238 if (!dircache_is_enabled()
239 && !dircache_is_initializing())
241 if (global_status
.dircache_size
<= 0)
243 splash(0, str(LANG_SCANNING_DISK
));
246 result
= dircache_build(global_status
.dircache_size
);
251 /* Initialization of dircache failed. Manual action is
252 * necessary to enable dircache again.
254 splashf(0, "Dircache failed, disabled. Result: %d", result
);
255 global_settings
.dircache
= false;
263 global_status
.dircache_size
= dircache_get_cache_size();
275 static void init_tagcache(void) INIT_ATTR
;
276 static void init_tagcache(void)
279 #if CONFIG_CODEC == SWCODEC
280 long talked_tick
= 0;
284 while (!tagcache_is_initialized())
286 int ret
= tagcache_get_commit_step();
290 #if CONFIG_CODEC == SWCODEC
291 /* hwcodec can't use voice here, as the database commit
292 * uses the audio buffer. */
293 if(global_settings
.talk_menu
295 || TIME_AFTER(current_tick
, talked_tick
+7*HZ
)))
297 talked_tick
= current_tick
;
298 talk_id(LANG_TAGCACHE_INIT
, false);
299 talk_number(ret
, true);
300 talk_id(VOICE_OF
, true);
301 talk_number(tagcache_get_max_commit_step(), true);
304 #ifdef HAVE_LCD_BITMAP
307 splashf(0, "[%d/%d] %s", ret
, tagcache_get_max_commit_step(),
308 str(LANG_TAGCACHE_INIT
));
312 splashf(0, "%s [%d/%d]", str(LANG_TAGCACHE_INIT
), ret
,
313 tagcache_get_max_commit_step());
316 lcd_double_height(false);
317 lcd_putsf(0, 1, " DB [%d/%d]", ret
,
318 tagcache_get_max_commit_step());
335 #if (CONFIG_PLATFORM & PLATFORM_HOSTED)
337 static void init(void)
347 #ifdef HAVE_REMOTE_LCD
354 #if (CONFIG_PLATFORM & (PLATFORM_SDL|PLATFORM_MAEMO))
357 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
360 lang_init(core_language_builtin
, language_strings
,
361 LANG_LAST_INDEX_IN_ARRAY
);
365 /* Keep the order of this 3 (viewportmanager handles statusbars)
366 * Must be done before any code uses the multi-screen API */
367 gui_syncstatusbar_init(&statusbars
);
368 gui_sync_skin_init();
370 viewportmanager_init();
374 settings_load(SETTINGS_ALL
);
375 settings_apply(true);
377 init_dircache(false);
387 #if CONFIG_CODEC != SWCODEC
388 mp3_init( global_settings
.volume
,
389 global_settings
.bass
,
390 global_settings
.treble
,
391 global_settings
.balance
,
392 global_settings
.loudness
,
394 global_settings
.channel_config
,
395 global_settings
.stereo_width
,
396 global_settings
.mdb_strength
,
397 global_settings
.mdb_harmonics
,
398 global_settings
.mdb_center
,
399 global_settings
.mdb_shape
,
400 global_settings
.mdb_enable
,
401 global_settings
.superbass
);
403 /* audio_init must to know the size of voice buffer so init voice first */
405 #endif /* CONFIG_CODEC != SWCODEC */
408 #if CONFIG_CODEC == SWCODEC && defined (HAVE_PITCHSCREEN)
410 #endif /* CONFIG_CODEC == SWCODEC */
414 settings_apply_skins();
419 static void init(void) INIT_ATTR
;
420 static void init(void)
423 bool mounted
= false;
424 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
425 /* if nobody initialized ATA before, I consider this a cold start */
426 bool coldstart
= (PACR2
& 0x4000) != 0; /* starting from Flash */
430 #if defined(IPOD_VIDEO)
431 audiobufend
=(unsigned char *)audiobufend_lds
;
432 if(MEMORYSIZE
==64 && probed_ramsize
!=64)
434 audiobufend
-= (32<<20);
439 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
440 set_cpu_frequency(CPUFREQ_NORMAL
);
442 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS
);
459 /* current_tick should be ticking by now */
463 #ifdef HAVE_REMOTE_LCD
471 lang_init(core_language_builtin
, language_strings
,
472 LANG_LAST_INDEX_IN_ARRAY
);
486 CHART(">settings_load(RTC)");
487 settings_load(SETTINGS_RTC
); /* early load parts of global_settings */
488 CHART("<settings_load(RTC)");
494 #if CONFIG_USBOTG == USBOTG_ISP1362
496 #elif CONFIG_USBOTG == USBOTG_M5636
510 /* Keep the order of this 3 (viewportmanager handles statusbars)
511 * Must be done before any code uses the multi-screen API */
512 CHART(">gui_syncstatusbar_init");
513 gui_syncstatusbar_init(&statusbars
);
514 CHART("<gui_syncstatusbar_init");
515 CHART(">sb_skin_init");
517 CHART("<sb_skin_init");
518 CHART(">gui_sync_wps_init");
519 gui_sync_skin_init();
520 CHART("<gui_sync_wps_init");
521 CHART(">viewportmanager_init");
522 viewportmanager_init();
523 CHART("<viewportmanager_init");
525 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
526 /* charger_inserted() can't be used here because power_thread()
527 hasn't checked power_input_status() yet */
528 if (coldstart
&& (power_input_status() & POWER_INPUT_MAIN_CHARGER
)
529 && !global_settings
.car_adapter_mode
530 #ifdef ATA_POWER_PLAYERSTYLE
531 && !ide_powered() /* relies on probing result from bootloader */
535 rc
= charging_screen(); /* display a "charging" screen */
536 if (rc
== 1) /* charger removed */
538 /* "On" pressed or USB connected: proceed */
539 show_logo(); /* again, to provide better visual feedback */
544 disk_init_subsystem();
545 CHART(">storage_init");
547 CHART("<storage_init");
550 #ifdef HAVE_LCD_BITMAP
552 lcd_putsf(0, 1, "ATA error: %d", rc
);
553 lcd_puts(0, 3, "Press ON to debug");
555 while(!(button_get(true) & BUTTON_REL
)); /* DO NOT CHANGE TO ACTION SYSTEM */
558 panicf("ata: %d", rc
);
561 #ifdef HAVE_EEPROM_SETTINGS
562 CHART(">eeprom_settings_init");
563 eeprom_settings_init();
564 CHART("<eeprom_settings_init");
567 #ifndef HAVE_USBSTACK
568 usb_start_monitoring();
569 while (usb_detect() == USB_INSERTED
)
571 #ifdef HAVE_EEPROM_SETTINGS
572 firmware_settings
.disk_clean
= false;
574 /* enter USB mode early, before trying to mount */
575 if (button_get_w_tmo(HZ
/10) == SYS_USB_CONNECTED
)
576 #if (CONFIG_STORAGE & STORAGE_MMC)
577 if (!mmc_touched() ||
578 (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED
))
581 gui_usb_screen_run(true);
582 mounted
= true; /* mounting done @ end of USB mode */
584 #ifdef HAVE_USB_POWER
585 if (usb_powered()) /* avoid deadlock */
593 CHART(">disk_mount_all");
594 rc
= disk_mount_all();
595 CHART("<disk_mount_all");
599 lcd_puts(0, 0, "No partition");
600 lcd_puts(0, 1, "found.");
601 #ifdef HAVE_LCD_BITMAP
602 lcd_puts(0, 2, "Insert USB cable");
603 lcd_puts(0, 3, "and fix it.");
607 while(button_get(true) != SYS_USB_CONNECTED
) {};
608 gui_usb_screen_run(true);
613 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
614 (CONFIG_KEYPAD == IRIVER_H10_PAD)
615 #ifdef SETTINGS_RESET
616 /* Reset settings if holding the reset button. (Rec on Archos,
618 if ((button_status() & SETTINGS_RESET
) == SETTINGS_RESET
)
620 /* Reset settings if the hold button is turned on */
624 splash(HZ
*2, str(LANG_RESET_DONE_CLEAR
));
630 CHART(">settings_load(ALL)");
631 settings_load(SETTINGS_ALL
);
632 CHART("<settings_load(ALL)");
635 CHART(">init_dircache(true)");
636 rc
= init_dircache(true);
637 CHART("<init_dircache(true)");
641 remove(TAGCACHE_STATEFILE
);
645 CHART(">settings_apply(true)");
646 settings_apply(true);
647 CHART("<settings_apply(true)");
648 CHART(">init_dircache(false)");
649 init_dircache(false);
650 CHART("<init_dircache(false)");
652 CHART(">init_tagcache");
654 CHART("<init_tagcache");
657 #ifdef HAVE_EEPROM_SETTINGS
658 if (firmware_settings
.initialized
)
660 /* In case we crash. */
661 firmware_settings
.disk_clean
= false;
662 CHART(">eeprom_settings_store");
663 eeprom_settings_store();
664 CHART("<eeprom_settings_store");
671 #if CONFIG_CODEC == SWCODEC && defined (HAVE_PITCHSCREEN)
673 #endif /* CONFIG_CODEC == SWCODEC */
676 #if CONFIG_CODEC != SWCODEC
677 /* No buffer allocation (see buffer.c) may take place after the call to
678 audio_init() since the mpeg thread takes the rest of the buffer space */
679 mp3_init( global_settings
.volume
,
680 global_settings
.bass
,
681 global_settings
.treble
,
682 global_settings
.balance
,
683 global_settings
.loudness
,
685 global_settings
.channel_config
,
686 global_settings
.stereo_width
,
687 global_settings
.mdb_strength
,
688 global_settings
.mdb_harmonics
,
689 global_settings
.mdb_center
,
690 global_settings
.mdb_shape
,
691 global_settings
.mdb_enable
,
692 global_settings
.superbass
);
694 /* audio_init must to know the size of voice buffer so init voice first */
696 #endif /* CONFIG_CODEC != SWCODEC */
698 CHART(">audio_init");
700 CHART("<audio_init");
702 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
706 /* runtime database has to be initialized after audio_init() */
710 car_adapter_mode_init();
712 #ifdef IPOD_ACCESSORY_PROTOCOL
713 iap_setup(global_settings
.serial_bitrate
);
715 #ifdef HAVE_ACCESSORY_SUPPLY
716 accessory_supply_set(global_settings
.accessory_supply
);
718 #ifdef HAVE_LINEOUT_POWEROFF
719 lineout_set(global_settings
.lineout_active
);
721 #ifdef HAVE_HOTSWAP_STORAGE_AS_MAIN
722 CHART("<check_bootfile(false)");
723 check_bootfile(false); /* remember write time and filesize */
724 CHART(">check_bootfile(false)");
726 CHART("<settings_apply_skins");
727 settings_apply_skins();
728 CHART(">settings_apply_skins");
732 void cop_main(void) MAIN_NORETURN_ATTR
;
735 /* This is the entry point for the coprocessor
736 Anyone not running an upgraded bootloader will never reach this point,
737 so it should not be assumed that the coprocessor be usable even on
738 platforms which support it.
740 A kernel thread is initially setup on the coprocessor and immediately
741 destroyed for purposes of continuity. The cop sits idle until at least
742 one thread exists on it. */
747 /* This should never be reached */
755 #endif /* SIMULATOR */