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"
56 #include "core_alloc.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"
80 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
81 #include "notification.h"
83 #include "shortcuts.h"
85 #ifdef IPOD_ACCESSORY_PROTOCOL
89 #if (CONFIG_CODEC == SWCODEC)
93 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
94 #include "pcm_record.h"
98 #define SETTINGS_RESET BUTTON_REC
99 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
100 #define SETTINGS_RESET BUTTON_A
106 #if (CONFIG_STORAGE & STORAGE_MMC)
110 #ifdef HAVE_REMOTE_LCD
111 #include "lcd-remote.h"
114 #if CONFIG_USBOTG == USBOTG_ISP1362
118 #if CONFIG_USBOTG == USBOTG_M5636
122 #ifdef HAVE_HARDWARE_CLICK
126 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
127 #define MAIN_NORETURN_ATTR NORETURN_ATTR
129 /* gcc adds an implicit 'return 0;' at the end of main(), causing a warning
130 * with noreturn attribute */
131 #define MAIN_NORETURN_ATTR
134 #if (CONFIG_PLATFORM & (PLATFORM_SDL|PLATFORM_MAEMO|PLATFORM_PANDORA))
136 #include "sim_tasks.h"
138 #include "system-sdl.h"
139 #define HAVE_ARGV_MAIN
140 /* Don't use SDL_main on windows -> no more stdio redirection */
146 /*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
148 static void init(void);
149 /* main(), and various functions called by main() and init() may be
150 * be INIT_ATTR. These functions must not be called after the final call
151 * to root_menu() at the end of main()
152 * see definition of INIT_ATTR in config.h */
153 #ifdef HAVE_ARGV_MAIN
154 int main(int argc
, char *argv
[]) INIT_ATTR MAIN_NORETURN_ATTR
;
155 int main(int argc
, char *argv
[])
157 sys_handle_argv(argc
, argv
);
159 int main(void) INIT_ATTR MAIN_NORETURN_ATTR
;
168 screens
[i
].clear_display();
171 #ifdef HAVE_LCD_BITMAP
175 /* Keep the order of this 3
176 * Must be done before any code uses the multi-screen API */
178 /* All threads should be created and public queues registered by now */
179 usb_start_monitoring();
184 char filename
[MAX_PATH
];
192 if(file_exists(file
)) /* no complaint if it doesn't exist */
194 plugin_load(file
, NULL
); /* start if it does */
197 #endif /* #ifdef AUTOROCK */
199 global_status
.last_volume_change
= 0;
200 /* no calls INIT_ATTR functions after this point anymore!
201 * see definition of INIT_ATTR in config.h */
206 static int init_dircache(bool preinit
) INIT_ATTR
;
207 static int init_dircache(bool preinit
)
216 if (!global_settings
.dircache
)
219 # ifdef HAVE_EEPROM_SETTINGS
220 if (firmware_settings
.initialized
&& firmware_settings
.disk_clean
223 result
= dircache_load();
227 firmware_settings
.disk_clean
= false;
228 if (global_status
.dircache_size
<= 0)
230 /* This will be in default language, settings are not
231 applied yet. Not really any easy way to fix that. */
232 splash(0, str(LANG_SCANNING_DISK
));
236 dircache_build(global_status
.dircache_size
);
245 if (!dircache_is_enabled()
246 && !dircache_is_initializing())
248 if (global_status
.dircache_size
<= 0)
250 splash(0, str(LANG_SCANNING_DISK
));
253 result
= dircache_build(global_status
.dircache_size
);
258 /* Initialization of dircache failed. Manual action is
259 * necessary to enable dircache again.
261 splashf(0, "Dircache failed, disabled. Result: %d", result
);
262 global_settings
.dircache
= false;
270 global_status
.dircache_size
= dircache_get_cache_size();
282 static void init_tagcache(void) INIT_ATTR
;
283 static void init_tagcache(void)
286 #if 0 /* CONFIG_CODEC == SWCODEC */
287 long talked_tick
= 0;
291 while (!tagcache_is_initialized())
293 int ret
= tagcache_get_commit_step();
297 #if 0 /* FIXME: Audio isn't even initialized yet! */ /* CONFIG_CODEC == SWCODEC */
298 /* hwcodec can't use voice here, as the database commit
299 * uses the audio buffer. */
300 if(global_settings
.talk_menu
302 || TIME_AFTER(current_tick
, talked_tick
+7*HZ
)))
304 talked_tick
= current_tick
;
305 talk_id(LANG_TAGCACHE_INIT
, false);
306 talk_number(ret
, true);
307 talk_id(VOICE_OF
, true);
308 talk_number(tagcache_get_max_commit_step(), true);
311 #ifdef HAVE_LCD_BITMAP
314 splashf(0, "[%d/%d] %s", ret
, tagcache_get_max_commit_step(),
315 str(LANG_TAGCACHE_INIT
));
319 splashf(0, "%s [%d/%d]", str(LANG_TAGCACHE_INIT
), ret
,
320 tagcache_get_max_commit_step());
323 lcd_double_height(false);
324 lcd_putsf(0, 1, " DB [%d/%d]", ret
,
325 tagcache_get_max_commit_step());
342 #if (CONFIG_PLATFORM & PLATFORM_HOSTED)
344 static void init(void)
347 core_allocator_init();
354 #ifdef HAVE_REMOTE_LCD
357 #ifdef HAVE_LCD_BITMAP
359 global_status
.font_id
[i
] = FONT_SYSFIXED
;
369 #if (CONFIG_PLATFORM & PLATFORM_ANDROID)
372 lang_init(core_language_builtin
, language_strings
,
373 LANG_LAST_INDEX_IN_ARRAY
);
380 /* Keep the order of this 3 (viewportmanager handles statusbars)
381 * Must be done before any code uses the multi-screen API */
382 gui_syncstatusbar_init(&statusbars
);
383 gui_sync_skin_init();
385 viewportmanager_init();
388 #if CONFIG_CODEC == SWCODEC
392 settings_load(SETTINGS_ALL
);
393 settings_apply(true);
395 init_dircache(false);
404 #if CONFIG_CODEC != SWCODEC
405 mp3_init( global_settings
.volume
,
406 global_settings
.bass
,
407 global_settings
.treble
,
408 global_settings
.balance
,
409 global_settings
.loudness
,
411 global_settings
.channel_config
,
412 global_settings
.stereo_width
,
413 global_settings
.mdb_strength
,
414 global_settings
.mdb_harmonics
,
415 global_settings
.mdb_center
,
416 global_settings
.mdb_shape
,
417 global_settings
.mdb_enable
,
418 global_settings
.superbass
);
419 #endif /* CONFIG_CODEC != SWCODEC */
425 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING)
429 settings_apply_skins();
434 static void init(void) INIT_ATTR
;
435 static void init(void)
438 bool mounted
= false;
439 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
440 /* if nobody initialized ATA before, I consider this a cold start */
441 bool coldstart
= (PACR2
& 0x4000) != 0; /* starting from Flash */
445 core_allocator_init();
448 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
449 set_cpu_frequency(CPUFREQ_NORMAL
);
451 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS
);
464 /* current_tick should be ticking by now */
468 #ifdef HAVE_REMOTE_LCD
471 #ifdef HAVE_LCD_BITMAP
473 global_status
.font_id
[i
] = FONT_SYSFIXED
;
482 lang_init(core_language_builtin
, language_strings
,
483 LANG_LAST_INDEX_IN_ARRAY
);
493 #ifdef ROCKBOX_HAS_LOGDISKF
501 CHART(">settings_load(RTC)");
502 settings_load(SETTINGS_RTC
); /* early load parts of global_settings */
503 CHART("<settings_load(RTC)");
509 #if CONFIG_USBOTG == USBOTG_ISP1362
511 #elif CONFIG_USBOTG == USBOTG_M5636
519 /* Don't initialize power management here if it could incorrectly
520 * measure battery voltage, and it's not needed for charging. */
521 #if !defined(NEED_ATA_POWER_BATT_MEASURE) || \
522 (CONFIG_CHARGING > CHARGING_MONITOR)
530 #ifdef HAVE_HARDWARE_CLICK
534 /* Keep the order of this 3 (viewportmanager handles statusbars)
535 * Must be done before any code uses the multi-screen API */
536 CHART(">gui_syncstatusbar_init");
537 gui_syncstatusbar_init(&statusbars
);
538 CHART("<gui_syncstatusbar_init");
539 CHART(">sb_skin_init");
541 CHART("<sb_skin_init");
542 CHART(">gui_sync_wps_init");
543 gui_sync_skin_init();
544 CHART("<gui_sync_wps_init");
545 CHART(">viewportmanager_init");
546 viewportmanager_init();
547 CHART("<viewportmanager_init");
549 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
550 /* charger_inserted() can't be used here because power_thread()
551 hasn't checked power_input_status() yet */
552 if (coldstart
&& (power_input_status() & POWER_INPUT_MAIN_CHARGER
)
553 && !global_settings
.car_adapter_mode
554 #ifdef ATA_POWER_PLAYERSTYLE
555 && !ide_powered() /* relies on probing result from bootloader */
559 rc
= charging_screen(); /* display a "charging" screen */
560 if (rc
== 1) /* charger removed */
562 /* "On" pressed or USB connected: proceed */
563 show_logo(); /* again, to provide better visual feedback */
568 disk_init_subsystem();
569 CHART(">storage_init");
571 CHART("<storage_init");
574 #ifdef HAVE_LCD_BITMAP
576 lcd_putsf(0, 1, "ATA error: %d", rc
);
577 lcd_puts(0, 3, "Press ON to debug");
579 while(!(button_get(true) & BUTTON_REL
)); /* DO NOT CHANGE TO ACTION SYSTEM */
582 panicf("ata: %d", rc
);
585 #if defined(NEED_ATA_POWER_BATT_MEASURE) && \
586 (CONFIG_CHARGING <= CHARGING_MONITOR)
587 /* After storage_init(), ATA power must be on, so battery voltage
588 * can be measured. Initialize power management if it was delayed. */
591 #ifdef HAVE_EEPROM_SETTINGS
592 CHART(">eeprom_settings_init");
593 eeprom_settings_init();
594 CHART("<eeprom_settings_init");
597 #ifndef HAVE_USBSTACK
598 usb_start_monitoring();
599 while (usb_detect() == USB_INSERTED
)
601 #ifdef HAVE_EEPROM_SETTINGS
602 firmware_settings
.disk_clean
= false;
604 /* enter USB mode early, before trying to mount */
605 if (button_get_w_tmo(HZ
/10) == SYS_USB_CONNECTED
)
606 #if (CONFIG_STORAGE & STORAGE_MMC)
607 if (!mmc_touched() ||
608 (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED
))
611 gui_usb_screen_run(true);
612 mounted
= true; /* mounting done @ end of USB mode */
614 #ifdef HAVE_USB_POWER
615 if (usb_powered()) /* avoid deadlock */
623 CHART(">disk_mount_all");
624 rc
= disk_mount_all();
625 CHART("<disk_mount_all");
629 lcd_puts(0, 0, "No partition");
630 lcd_puts(0, 1, "found.");
631 #ifdef HAVE_LCD_BITMAP
632 lcd_puts(0, 2, "Insert USB cable");
633 lcd_puts(0, 3, "and fix it.");
637 while(button_get(true) != SYS_USB_CONNECTED
) {};
638 gui_usb_screen_run(true);
643 #if CONFIG_CODEC == SWCODEC
647 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
648 (CONFIG_KEYPAD == IRIVER_H10_PAD)
649 #ifdef SETTINGS_RESET
650 /* Reset settings if holding the reset button. (Rec on Archos,
652 if ((button_status() & SETTINGS_RESET
) == SETTINGS_RESET
)
654 /* Reset settings if the hold button is turned on */
658 splash(HZ
*2, str(LANG_RESET_DONE_CLEAR
));
664 CHART(">settings_load(ALL)");
665 settings_load(SETTINGS_ALL
);
666 CHART("<settings_load(ALL)");
669 CHART(">init_dircache(true)");
670 rc
= init_dircache(true);
671 CHART("<init_dircache(true)");
675 remove(TAGCACHE_STATEFILE
);
679 CHART(">settings_apply(true)");
680 settings_apply(true);
681 CHART("<settings_apply(true)");
682 CHART(">init_dircache(false)");
683 init_dircache(false);
684 CHART("<init_dircache(false)");
686 CHART(">init_tagcache");
688 CHART("<init_tagcache");
691 #ifdef HAVE_EEPROM_SETTINGS
692 if (firmware_settings
.initialized
)
694 /* In case we crash. */
695 firmware_settings
.disk_clean
= false;
696 CHART(">eeprom_settings_store");
697 eeprom_settings_store();
698 CHART("<eeprom_settings_store");
707 #if CONFIG_CODEC != SWCODEC
708 /* No buffer allocation (see buffer.c) may take place after the call to
709 audio_init() since the mpeg thread takes the rest of the buffer space */
710 mp3_init( global_settings
.volume
,
711 global_settings
.bass
,
712 global_settings
.treble
,
713 global_settings
.balance
,
714 global_settings
.loudness
,
716 global_settings
.channel_config
,
717 global_settings
.stereo_width
,
718 global_settings
.mdb_strength
,
719 global_settings
.mdb_harmonics
,
720 global_settings
.mdb_center
,
721 global_settings
.mdb_shape
,
722 global_settings
.mdb_enable
,
723 global_settings
.superbass
);
724 #endif /* CONFIG_CODEC != SWCODEC */
726 CHART(">audio_init");
728 CHART("<audio_init");
730 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING)
734 /* runtime database has to be initialized after audio_init() */
738 car_adapter_mode_init();
740 #ifdef IPOD_ACCESSORY_PROTOCOL
741 iap_setup(global_settings
.serial_bitrate
);
743 #ifdef HAVE_ACCESSORY_SUPPLY
744 accessory_supply_set(global_settings
.accessory_supply
);
746 #ifdef HAVE_LINEOUT_POWEROFF
747 lineout_set(global_settings
.lineout_active
);
749 #ifdef HAVE_HOTSWAP_STORAGE_AS_MAIN
750 CHART("<check_bootfile(false)");
751 check_bootfile(false); /* remember write time and filesize */
752 CHART(">check_bootfile(false)");
754 CHART("<settings_apply_skins");
755 settings_apply_skins();
756 CHART(">settings_apply_skins");
760 void cop_main(void) MAIN_NORETURN_ATTR
;
763 /* This is the entry point for the coprocessor
764 Anyone not running an upgraded bootloader will never reach this point,
765 so it should not be assumed that the coprocessor be usable even on
766 platforms which support it.
768 A kernel thread is initially setup on the coprocessor and immediately
769 destroyed for purposes of continuity. The cop sits idle until at least
770 one thread exists on it. */
775 /* This should never be reached */
783 #endif /* SIMULATOR */