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"
58 #include "usb_screen.h"
71 #include "eeprom_settings.h"
72 #include "scrobbler.h"
75 #include "statusbar-skinned.h"
76 #include "bootchart.h"
78 #ifdef IPOD_ACCESSORY_PROTOCOL
82 #if (CONFIG_CODEC == SWCODEC)
86 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
87 #include "pcm_record.h"
91 #define SETTINGS_RESET BUTTON_REC
92 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
93 #define SETTINGS_RESET BUTTON_A
99 #if (CONFIG_STORAGE & STORAGE_MMC)
103 #ifdef HAVE_REMOTE_LCD
104 #include "lcd-remote.h"
107 #if CONFIG_USBOTG == USBOTG_ISP1362
111 #if CONFIG_USBOTG == USBOTG_M5636
115 #if (CONFIG_PLATFORM & PLATFORM_HOSTED)
116 #include "sim_tasks.h"
120 #include "system-sdl.h"
123 /*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
125 static void init(void);
128 #if defined(WIN32) && defined(main)
129 /* Don't use SDL_main on windows -> no more stdio redirection */
132 int main(int argc
, char *argv
[])
137 sys_handle_argv(argc
, argv
);
139 /* main(), and various functions called by main() and init() may be
140 * be INIT_ATTR. These functions must not be called after the final call
141 * to root_menu() at the end of main()
142 * see definition of INIT_ATTR in config.h */
143 int main(void) INIT_ATTR
__attribute__((noreturn
));
153 screens
[i
].clear_display();
156 #ifdef HAVE_LCD_BITMAP
160 /* Keep the order of this 3
161 * Must be done before any code uses the multi-screen API */
163 /* All threads should be created and public queues registered by now */
164 usb_start_monitoring();
169 char filename
[MAX_PATH
];
170 const char *file
= get_user_file_path(
176 "/autostart.rock", NEED_WRITE
|IS_FILE
, filename
, sizeof(filename
));
177 if(file_exists(file
)) /* no complaint if it doesn't exist */
179 plugin_load(file
, NULL
); /* start if it does */
182 #endif /* #ifdef AUTOROCK */
184 global_status
.last_volume_change
= 0;
185 /* no calls INIT_ATTR functions after this point anymore!
186 * see definition of INIT_ATTR in config.h */
191 static int init_dircache(bool preinit
) INIT_ATTR
;
192 static int init_dircache(bool preinit
)
201 if (!global_settings
.dircache
)
204 # ifdef HAVE_EEPROM_SETTINGS
205 if (firmware_settings
.initialized
&& firmware_settings
.disk_clean
208 result
= dircache_load();
212 firmware_settings
.disk_clean
= false;
213 if (global_status
.dircache_size
<= 0)
215 /* This will be in default language, settings are not
216 applied yet. Not really any easy way to fix that. */
217 splash(0, str(LANG_SCANNING_DISK
));
221 dircache_build(global_status
.dircache_size
);
230 if (!dircache_is_enabled()
231 && !dircache_is_initializing())
233 if (global_status
.dircache_size
<= 0)
235 splash(0, str(LANG_SCANNING_DISK
));
238 result
= dircache_build(global_status
.dircache_size
);
243 /* Initialization of dircache failed. Manual action is
244 * necessary to enable dircache again.
246 splashf(0, "Dircache failed, disabled. Result: %d", result
);
247 global_settings
.dircache
= false;
255 global_status
.dircache_size
= dircache_get_cache_size();
267 static void init_tagcache(void) INIT_ATTR
;
268 static void init_tagcache(void)
271 #if CONFIG_CODEC == SWCODEC
272 long talked_tick
= 0;
276 while (!tagcache_is_initialized())
278 int ret
= tagcache_get_commit_step();
282 #if CONFIG_CODEC == SWCODEC
283 /* hwcodec can't use voice here, as the database commit
284 * uses the audio buffer. */
285 if(global_settings
.talk_menu
287 || TIME_AFTER(current_tick
, talked_tick
+7*HZ
)))
289 talked_tick
= current_tick
;
290 talk_id(LANG_TAGCACHE_INIT
, false);
291 talk_number(ret
, true);
292 talk_id(VOICE_OF
, true);
293 talk_number(tagcache_get_max_commit_step(), true);
296 #ifdef HAVE_LCD_BITMAP
299 splashf(0, "[%d/%d] %s", ret
, tagcache_get_max_commit_step(),
300 str(LANG_TAGCACHE_INIT
));
304 splashf(0, "%s [%d/%d]", str(LANG_TAGCACHE_INIT
), ret
,
305 tagcache_get_max_commit_step());
308 lcd_double_height(false);
309 lcd_putsf(0, 1, " DB [%d/%d]", ret
,
310 tagcache_get_max_commit_step());
327 #if (CONFIG_PLATFORM & PLATFORM_HOSTED)
329 static void init(void)
336 #ifdef HAVE_REMOTE_LCD
344 lang_init(core_language_builtin
, language_strings
,
345 LANG_LAST_INDEX_IN_ARRAY
);
349 /* Keep the order of this 3 (viewportmanager handles statusbars)
350 * Must be done before any code uses the multi-screen API */
351 gui_syncstatusbar_init(&statusbars
);
354 viewportmanager_init();
358 settings_load(SETTINGS_ALL
);
359 settings_apply(true);
361 init_dircache(false);
371 #if CONFIG_CODEC != SWCODEC
372 mp3_init( global_settings
.volume
,
373 global_settings
.bass
,
374 global_settings
.treble
,
375 global_settings
.balance
,
376 global_settings
.loudness
,
378 global_settings
.channel_config
,
379 global_settings
.stereo_width
,
380 global_settings
.mdb_strength
,
381 global_settings
.mdb_harmonics
,
382 global_settings
.mdb_center
,
383 global_settings
.mdb_shape
,
384 global_settings
.mdb_enable
,
385 global_settings
.superbass
);
387 /* audio_init must to know the size of voice buffer so init voice first */
389 #endif /* CONFIG_CODEC != SWCODEC */
392 #if CONFIG_CODEC == SWCODEC
394 #endif /* CONFIG_CODEC == SWCODEC */
397 button_clear_queue(); /* Empty the keyboard buffer */
399 settings_apply_skins();
404 static void init(void) INIT_ATTR
;
405 static void init(void)
408 bool mounted
= false;
409 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
410 /* if nobody initialized ATA before, I consider this a cold start */
411 bool coldstart
= (PACR2
& 0x4000) != 0; /* starting from Flash */
417 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
418 set_cpu_frequency(CPUFREQ_NORMAL
);
420 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS
);
437 /* current_tick should be ticking by now */
441 #ifdef HAVE_REMOTE_LCD
449 lang_init(core_language_builtin
, language_strings
,
450 LANG_LAST_INDEX_IN_ARRAY
);
464 CHART(">settings_load(RTC)");
465 settings_load(SETTINGS_RTC
); /* early load parts of global_settings */
466 CHART("<settings_load(RTC)");
472 #if CONFIG_USBOTG == USBOTG_ISP1362
474 #elif CONFIG_USBOTG == USBOTG_M5636
488 /* Keep the order of this 3 (viewportmanager handles statusbars)
489 * Must be done before any code uses the multi-screen API */
490 CHART(">gui_syncstatusbar_init");
491 gui_syncstatusbar_init(&statusbars
);
492 CHART("<gui_syncstatusbar_init");
493 CHART(">sb_skin_init");
495 CHART("<sb_skin_init");
496 CHART(">gui_sync_wps_init");
498 CHART("<gui_sync_wps_init");
499 CHART(">viewportmanager_init");
500 viewportmanager_init();
501 CHART("<viewportmanager_init");
503 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
504 /* charger_inserted() can't be used here because power_thread()
505 hasn't checked power_input_status() yet */
506 if (coldstart
&& (power_input_status() & POWER_INPUT_MAIN_CHARGER
)
507 && !global_settings
.car_adapter_mode
508 #ifdef ATA_POWER_PLAYERSTYLE
509 && !ide_powered() /* relies on probing result from bootloader */
513 rc
= charging_screen(); /* display a "charging" screen */
514 if (rc
== 1) /* charger removed */
516 /* "On" pressed or USB connected: proceed */
517 show_logo(); /* again, to provide better visual feedback */
522 disk_init_subsystem();
523 CHART(">storage_init");
525 CHART("<storage_init");
528 #ifdef HAVE_LCD_BITMAP
530 lcd_putsf(0, 1, "ATA error: %d", rc
);
531 lcd_puts(0, 3, "Press ON to debug");
533 while(!(button_get(true) & BUTTON_REL
)); /*DO NOT CHANGE TO ACTION SYSTEM */
536 panicf("ata: %d", rc
);
539 #ifdef HAVE_EEPROM_SETTINGS
540 CHART(">eeprom_settings_init");
541 eeprom_settings_init();
542 CHART("<eeprom_settings_init");
545 #ifndef HAVE_USBSTACK
546 usb_start_monitoring();
547 while (usb_detect() == USB_INSERTED
)
549 #ifdef HAVE_EEPROM_SETTINGS
550 firmware_settings
.disk_clean
= false;
552 /* enter USB mode early, before trying to mount */
553 if (button_get_w_tmo(HZ
/10) == SYS_USB_CONNECTED
)
554 #if (CONFIG_STORAGE & STORAGE_MMC)
555 if (!mmc_touched() ||
556 (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED
))
559 gui_usb_screen_run();
560 mounted
= true; /* mounting done @ end of USB mode */
562 #ifdef HAVE_USB_POWER
563 if (usb_powered()) /* avoid deadlock */
571 CHART(">disk_mount_all");
572 rc
= disk_mount_all();
573 CHART("<disk_mount_all");
577 lcd_puts(0, 0, "No partition");
578 lcd_puts(0, 1, "found.");
579 #ifdef HAVE_LCD_BITMAP
580 lcd_puts(0, 2, "Insert USB cable");
581 lcd_puts(0, 3, "and fix it.");
585 while(button_get(true) != SYS_USB_CONNECTED
) {};
586 gui_usb_screen_run();
591 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
592 (CONFIG_KEYPAD == IRIVER_H10_PAD)
593 #ifdef SETTINGS_RESET
594 /* Reset settings if holding the reset button. (Rec on Archos,
596 if ((button_status() & SETTINGS_RESET
) == SETTINGS_RESET
)
598 /* Reset settings if the hold button is turned on */
602 splash(HZ
*2, str(LANG_RESET_DONE_CLEAR
));
608 CHART(">settings_load(ALL)");
609 settings_load(SETTINGS_ALL
);
610 CHART("<settings_load(ALL)");
613 CHART(">init_dircache(true)");
614 rc
= init_dircache(true);
615 CHART("<init_dircache(true)");
619 remove(TAGCACHE_STATEFILE
);
623 CHART(">settings_apply(true)");
624 settings_apply(true);
625 CHART("<settings_apply(true)");
626 CHART(">init_dircache(false)");
627 init_dircache(false);
628 CHART("<init_dircache(false)");
630 CHART(">init_tagcache");
632 CHART("<init_tagcache");
635 #ifdef HAVE_EEPROM_SETTINGS
636 if (firmware_settings
.initialized
)
638 /* In case we crash. */
639 firmware_settings
.disk_clean
= false;
640 CHART(">eeprom_settings_store");
641 eeprom_settings_store();
642 CHART("<eeprom_settings_store");
649 #if CONFIG_CODEC == SWCODEC
651 #endif /* CONFIG_CODEC == SWCODEC */
654 #if CONFIG_CODEC != SWCODEC
655 /* No buffer allocation (see buffer.c) may take place after the call to
656 audio_init() since the mpeg thread takes the rest of the buffer space */
657 mp3_init( global_settings
.volume
,
658 global_settings
.bass
,
659 global_settings
.treble
,
660 global_settings
.balance
,
661 global_settings
.loudness
,
663 global_settings
.channel_config
,
664 global_settings
.stereo_width
,
665 global_settings
.mdb_strength
,
666 global_settings
.mdb_harmonics
,
667 global_settings
.mdb_center
,
668 global_settings
.mdb_shape
,
669 global_settings
.mdb_enable
,
670 global_settings
.superbass
);
672 /* audio_init must to know the size of voice buffer so init voice first */
674 #endif /* CONFIG_CODEC != SWCODEC */
676 CHART(">audio_init");
678 CHART("<audio_init");
680 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
684 /* runtime database has to be initialized after audio_init() */
688 car_adapter_mode_init();
690 #ifdef IPOD_ACCESSORY_PROTOCOL
691 iap_setup(global_settings
.serial_bitrate
);
693 #ifdef HAVE_ACCESSORY_SUPPLY
694 accessory_supply_set(global_settings
.accessory_supply
);
696 #ifdef HAVE_LINEOUT_POWEROFF
697 lineout_set(global_settings
.lineout_active
);
699 #ifdef HAVE_HOTSWAP_STORAGE_AS_MAIN
700 CHART("<check_bootfile(false)");
701 check_bootfile(false); /* remember write time and filesize */
702 CHART(">check_bootfile(false)");
704 CHART("<settings_apply_skins");
705 settings_apply_skins();
706 CHART(">settings_apply_skins");
710 void __attribute__((noreturn
)) cop_main(void)
712 /* This is the entry point for the coprocessor
713 Anyone not running an upgraded bootloader will never reach this point,
714 so it should not be assumed that the coprocessor be usable even on
715 platforms which support it.
717 A kernel thread is initially setup on the coprocessor and immediately
718 destroyed for purposes of continuity. The cop sits idle until at least
719 one thread exists on it. */
724 /* This should never be reached */
732 #endif /* SIMULATOR */