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 ****************************************************************************/
33 #include "filetypes.h"
38 #include "powermgmt.h"
45 #include "mp3_playback.h"
48 #include "backlight.h"
50 #include "debug_menu.h"
59 #include "usb_screen.h"
72 #include "eeprom_settings.h"
73 #include "scrobbler.h"
76 #include "statusbar-skinned.h"
77 #include "bootchart.h"
79 #ifdef IPOD_ACCESSORY_PROTOCOL
83 #if (CONFIG_CODEC == SWCODEC)
87 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
88 #include "pcm_record.h"
92 #define SETTINGS_RESET BUTTON_REC
93 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
94 #define SETTINGS_RESET BUTTON_A
100 #if (CONFIG_STORAGE & STORAGE_MMC)
104 #ifdef HAVE_REMOTE_LCD
105 #include "lcd-remote.h"
108 #if CONFIG_USBOTG == USBOTG_ISP1362
112 #if CONFIG_USBOTG == USBOTG_M5636
117 #include "sim_tasks.h"
118 #include "system-sdl.h"
121 /*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
123 static void init(void);
126 #if defined(WIN32) && defined(main)
127 /* Don't use SDL_main on windows -> no more stdio redirection */
130 int main(int argc
, char *argv
[])
132 sys_handle_argv(argc
, argv
);
134 /* main(), and various functions called by main() and init() may be
135 * be INIT_ATTR. These functions must not be called after the final call
136 * to root_menu() at the end of main()
137 * see definition of INIT_ATTR in config.h */
138 int main(void) INIT_ATTR
__attribute__((noreturn
));
148 screens
[i
].clear_display();
151 #ifdef HAVE_LCD_BITMAP
155 /* Keep the order of this 3
156 * Must be done before any code uses the multi-screen API */
158 /* All threads should be created and public queues registered by now */
159 usb_start_monitoring();
164 static const char filename
[] = PLUGIN_APPS_DIR
"/autostart.rock";
166 if(file_exists(filename
)) /* no complaint if it doesn't exist */
168 plugin_load((char*)filename
, NULL
); /* start if it does */
171 #endif /* #ifdef AUTOROCK */
173 global_status
.last_volume_change
= 0;
174 /* no calls INIT_ATTR functions after this point anymore!
175 * see definition of INIT_ATTR in config.h */
180 static int init_dircache(bool preinit
) INIT_ATTR
;
181 static int init_dircache(bool preinit
)
190 if (!global_settings
.dircache
)
193 # ifdef HAVE_EEPROM_SETTINGS
194 if (firmware_settings
.initialized
&& firmware_settings
.disk_clean
197 result
= dircache_load();
201 firmware_settings
.disk_clean
= false;
202 if (global_status
.dircache_size
<= 0)
204 /* This will be in default language, settings are not
205 applied yet. Not really any easy way to fix that. */
206 splash(0, str(LANG_SCANNING_DISK
));
210 dircache_build(global_status
.dircache_size
);
219 if (!dircache_is_enabled()
220 && !dircache_is_initializing())
222 if (global_status
.dircache_size
<= 0)
224 splash(0, str(LANG_SCANNING_DISK
));
227 result
= dircache_build(global_status
.dircache_size
);
232 /* Initialization of dircache failed. Manual action is
233 * necessary to enable dircache again.
235 splashf(0, "Dircache failed, disabled. Result: %d", result
);
236 global_settings
.dircache
= false;
244 global_status
.dircache_size
= dircache_get_cache_size();
256 static void init_tagcache(void) INIT_ATTR
;
257 static void init_tagcache(void)
260 #if CONFIG_CODEC == SWCODEC
261 long talked_tick
= 0;
265 while (!tagcache_is_initialized())
267 int ret
= tagcache_get_commit_step();
271 #if CONFIG_CODEC == SWCODEC
272 /* hwcodec can't use voice here, as the database commit
273 * uses the audio buffer. */
274 if(global_settings
.talk_menu
276 || TIME_AFTER(current_tick
, talked_tick
+7*HZ
)))
278 talked_tick
= current_tick
;
279 talk_id(LANG_TAGCACHE_INIT
, false);
280 talk_number(ret
, true);
281 talk_id(VOICE_OF
, true);
282 talk_number(tagcache_get_max_commit_step(), true);
285 #ifdef HAVE_LCD_BITMAP
288 splashf(0, "[%d/%d] %s", ret
, tagcache_get_max_commit_step(),
289 str(LANG_TAGCACHE_INIT
));
293 splashf(0, "%s [%d/%d]", str(LANG_TAGCACHE_INIT
), ret
,
294 tagcache_get_max_commit_step());
297 lcd_double_height(false);
298 lcd_putsf(0, 1, " DB [%d/%d]", ret
,
299 tagcache_get_max_commit_step());
318 static void init(void)
325 #ifdef HAVE_REMOTE_LCD
333 lang_init(core_language_builtin
, language_strings
,
334 LANG_LAST_INDEX_IN_ARRAY
);
338 /* Keep the order of this 3 (viewportmanager handles statusbars)
339 * Must be done before any code uses the multi-screen API */
340 gui_syncstatusbar_init(&statusbars
);
343 viewportmanager_init();
347 settings_load(SETTINGS_ALL
);
348 settings_apply(true);
350 init_dircache(false);
359 #if CONFIG_CODEC != SWCODEC
360 mp3_init( global_settings
.volume
,
361 global_settings
.bass
,
362 global_settings
.treble
,
363 global_settings
.balance
,
364 global_settings
.loudness
,
366 global_settings
.channel_config
,
367 global_settings
.stereo_width
,
368 global_settings
.mdb_strength
,
369 global_settings
.mdb_harmonics
,
370 global_settings
.mdb_center
,
371 global_settings
.mdb_shape
,
372 global_settings
.mdb_enable
,
373 global_settings
.superbass
);
375 /* audio_init must to know the size of voice buffer so init voice first */
377 #endif /* CONFIG_CODEC != SWCODEC */
380 #if CONFIG_CODEC == SWCODEC
382 #endif /* CONFIG_CODEC == SWCODEC */
385 button_clear_queue(); /* Empty the keyboard buffer */
387 settings_apply_skins();
392 static void init(void) INIT_ATTR
;
393 static void init(void)
396 bool mounted
= false;
397 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
398 /* if nobody initialized ATA before, I consider this a cold start */
399 bool coldstart
= (PACR2
& 0x4000) != 0; /* starting from Flash */
405 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
406 set_cpu_frequency(CPUFREQ_NORMAL
);
408 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS
);
425 /* current_tick should be ticking by now */
429 #ifdef HAVE_REMOTE_LCD
437 lang_init(core_language_builtin
, language_strings
,
438 LANG_LAST_INDEX_IN_ARRAY
);
452 CHART(">settings_load(RTC)");
453 settings_load(SETTINGS_RTC
); /* early load parts of global_settings */
454 CHART("<settings_load(RTC)");
460 #if CONFIG_USBOTG == USBOTG_ISP1362
462 #elif CONFIG_USBOTG == USBOTG_M5636
476 /* Keep the order of this 3 (viewportmanager handles statusbars)
477 * Must be done before any code uses the multi-screen API */
478 CHART(">gui_syncstatusbar_init");
479 gui_syncstatusbar_init(&statusbars
);
480 CHART("<gui_syncstatusbar_init");
481 CHART(">sb_skin_init");
483 CHART("<sb_skin_init");
484 CHART(">gui_sync_wps_init");
486 CHART("<gui_sync_wps_init");
487 CHART(">viewportmanager_init");
488 viewportmanager_init();
489 CHART("<viewportmanager_init");
491 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
492 /* charger_inserted() can't be used here because power_thread()
493 hasn't checked power_input_status() yet */
494 if (coldstart
&& (power_input_status() & POWER_INPUT_MAIN_CHARGER
)
495 && !global_settings
.car_adapter_mode
496 #ifdef ATA_POWER_PLAYERSTYLE
497 && !ide_powered() /* relies on probing result from bootloader */
501 rc
= charging_screen(); /* display a "charging" screen */
502 if (rc
== 1) /* charger removed */
504 /* "On" pressed or USB connected: proceed */
505 show_logo(); /* again, to provide better visual feedback */
509 CHART(">storage_init");
511 CHART("<storage_init");
514 #ifdef HAVE_LCD_BITMAP
516 lcd_putsf(0, 1, "ATA error: %d", rc
);
517 lcd_puts(0, 3, "Press ON to debug");
519 while(!(button_get(true) & BUTTON_REL
)); /*DO NOT CHANGE TO ACTION SYSTEM */
522 panicf("ata: %d", rc
);
525 #ifdef HAVE_EEPROM_SETTINGS
526 CHART(">eeprom_settings_init");
527 eeprom_settings_init();
528 CHART("<eeprom_settings_init");
531 #ifndef HAVE_USBSTACK
532 usb_start_monitoring();
533 while (usb_detect() == USB_INSERTED
)
535 #ifdef HAVE_EEPROM_SETTINGS
536 firmware_settings
.disk_clean
= false;
538 /* enter USB mode early, before trying to mount */
539 if (button_get_w_tmo(HZ
/10) == SYS_USB_CONNECTED
)
540 #if (CONFIG_STORAGE & STORAGE_MMC)
541 if (!mmc_touched() ||
542 (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED
))
545 gui_usb_screen_run();
546 mounted
= true; /* mounting done @ end of USB mode */
548 #ifdef HAVE_USB_POWER
549 if (usb_powered()) /* avoid deadlock */
557 CHART(">disk_mount_all");
558 rc
= disk_mount_all();
559 CHART("<disk_mount_all");
563 lcd_puts(0, 0, "No partition");
564 lcd_puts(0, 1, "found.");
565 #ifdef HAVE_LCD_BITMAP
566 lcd_puts(0, 2, "Insert USB cable");
567 lcd_puts(0, 3, "and fix it.");
571 while(button_get(true) != SYS_USB_CONNECTED
) {};
572 gui_usb_screen_run();
577 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
578 (CONFIG_KEYPAD == IRIVER_H10_PAD)
579 #ifdef SETTINGS_RESET
580 /* Reset settings if holding the reset button. (Rec on Archos,
582 if ((button_status() & SETTINGS_RESET
) == SETTINGS_RESET
)
584 /* Reset settings if the hold button is turned on */
588 splash(HZ
*2, str(LANG_RESET_DONE_CLEAR
));
594 CHART(">settings_load(ALL)");
595 settings_load(SETTINGS_ALL
);
596 CHART("<settings_load(ALL)");
599 CHART(">init_dircache(true)");
600 rc
= init_dircache(true);
601 CHART("<init_dircache(true)");
605 remove(TAGCACHE_STATEFILE
);
609 CHART(">settings_apply(true)");
610 settings_apply(true);
611 CHART("<settings_apply(true)");
612 CHART(">init_dircache(false)");
613 init_dircache(false);
614 CHART("<init_dircache(false)");
616 CHART(">init_tagcache");
618 CHART("<init_tagcache");
621 #ifdef HAVE_EEPROM_SETTINGS
622 if (firmware_settings
.initialized
)
624 /* In case we crash. */
625 firmware_settings
.disk_clean
= false;
626 CHART(">eeprom_settings_store");
627 eeprom_settings_store();
628 CHART("<eeprom_settings_store");
635 #if CONFIG_CODEC == SWCODEC
637 #endif /* CONFIG_CODEC == SWCODEC */
639 #if CONFIG_CODEC != SWCODEC
640 /* No buffer allocation (see buffer.c) may take place after the call to
641 audio_init() since the mpeg thread takes the rest of the buffer space */
642 mp3_init( global_settings
.volume
,
643 global_settings
.bass
,
644 global_settings
.treble
,
645 global_settings
.balance
,
646 global_settings
.loudness
,
648 global_settings
.channel_config
,
649 global_settings
.stereo_width
,
650 global_settings
.mdb_strength
,
651 global_settings
.mdb_harmonics
,
652 global_settings
.mdb_center
,
653 global_settings
.mdb_shape
,
654 global_settings
.mdb_enable
,
655 global_settings
.superbass
);
657 /* audio_init must to know the size of voice buffer so init voice first */
659 #endif /* CONFIG_CODEC != SWCODEC */
661 CHART(">audio_init");
663 CHART("<audio_init");
665 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
669 /* runtime database has to be initialized after audio_init() */
673 car_adapter_mode_init();
675 #ifdef IPOD_ACCESSORY_PROTOCOL
676 iap_setup(global_settings
.serial_bitrate
);
678 #ifdef HAVE_ACCESSORY_SUPPLY
679 accessory_supply_set(global_settings
.accessory_supply
);
681 #ifdef HAVE_LINEOUT_POWEROFF
682 lineout_set(global_settings
.lineout_active
);
684 #ifdef HAVE_HOTSWAP_STORAGE_AS_MAIN
685 CHART("<check_bootfile(false)");
686 check_bootfile(false); /* remember write time and filesize */
687 CHART(">check_bootfile(false)");
689 CHART("<settings_apply_skins");
690 settings_apply_skins();
691 CHART(">settings_apply_skins");
697 /* This is the entry point for the coprocessor
698 Anyone not running an upgraded bootloader will never reach this point,
699 so it should not be assumed that the coprocessor be usable even on
700 platforms which support it.
702 A kernel thread is initially setup on the coprocessor and immediately
703 destroyed for purposes of continuity. The cop sits idle until at least
704 one thread exists on it. */
706 /* 3G doesn't have Rolo or dual core support yet */
710 /* This should never be reached */