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);
370 #if CONFIG_CODEC != SWCODEC
371 mp3_init( global_settings
.volume
,
372 global_settings
.bass
,
373 global_settings
.treble
,
374 global_settings
.balance
,
375 global_settings
.loudness
,
377 global_settings
.channel_config
,
378 global_settings
.stereo_width
,
379 global_settings
.mdb_strength
,
380 global_settings
.mdb_harmonics
,
381 global_settings
.mdb_center
,
382 global_settings
.mdb_shape
,
383 global_settings
.mdb_enable
,
384 global_settings
.superbass
);
386 /* audio_init must to know the size of voice buffer so init voice first */
388 #endif /* CONFIG_CODEC != SWCODEC */
391 #if CONFIG_CODEC == SWCODEC
393 #endif /* CONFIG_CODEC == SWCODEC */
396 button_clear_queue(); /* Empty the keyboard buffer */
398 settings_apply_skins();
403 static void init(void) INIT_ATTR
;
404 static void init(void)
407 bool mounted
= false;
408 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
409 /* if nobody initialized ATA before, I consider this a cold start */
410 bool coldstart
= (PACR2
& 0x4000) != 0; /* starting from Flash */
416 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
417 set_cpu_frequency(CPUFREQ_NORMAL
);
419 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS
);
436 /* current_tick should be ticking by now */
440 #ifdef HAVE_REMOTE_LCD
448 lang_init(core_language_builtin
, language_strings
,
449 LANG_LAST_INDEX_IN_ARRAY
);
463 CHART(">settings_load(RTC)");
464 settings_load(SETTINGS_RTC
); /* early load parts of global_settings */
465 CHART("<settings_load(RTC)");
471 #if CONFIG_USBOTG == USBOTG_ISP1362
473 #elif CONFIG_USBOTG == USBOTG_M5636
487 /* Keep the order of this 3 (viewportmanager handles statusbars)
488 * Must be done before any code uses the multi-screen API */
489 CHART(">gui_syncstatusbar_init");
490 gui_syncstatusbar_init(&statusbars
);
491 CHART("<gui_syncstatusbar_init");
492 CHART(">sb_skin_init");
494 CHART("<sb_skin_init");
495 CHART(">gui_sync_wps_init");
497 CHART("<gui_sync_wps_init");
498 CHART(">viewportmanager_init");
499 viewportmanager_init();
500 CHART("<viewportmanager_init");
502 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
503 /* charger_inserted() can't be used here because power_thread()
504 hasn't checked power_input_status() yet */
505 if (coldstart
&& (power_input_status() & POWER_INPUT_MAIN_CHARGER
)
506 && !global_settings
.car_adapter_mode
507 #ifdef ATA_POWER_PLAYERSTYLE
508 && !ide_powered() /* relies on probing result from bootloader */
512 rc
= charging_screen(); /* display a "charging" screen */
513 if (rc
== 1) /* charger removed */
515 /* "On" pressed or USB connected: proceed */
516 show_logo(); /* again, to provide better visual feedback */
521 disk_init_subsystem();
522 CHART(">storage_init");
524 CHART("<storage_init");
527 #ifdef HAVE_LCD_BITMAP
529 lcd_putsf(0, 1, "ATA error: %d", rc
);
530 lcd_puts(0, 3, "Press ON to debug");
532 while(!(button_get(true) & BUTTON_REL
)); /*DO NOT CHANGE TO ACTION SYSTEM */
535 panicf("ata: %d", rc
);
538 #ifdef HAVE_EEPROM_SETTINGS
539 CHART(">eeprom_settings_init");
540 eeprom_settings_init();
541 CHART("<eeprom_settings_init");
544 #ifndef HAVE_USBSTACK
545 usb_start_monitoring();
546 while (usb_detect() == USB_INSERTED
)
548 #ifdef HAVE_EEPROM_SETTINGS
549 firmware_settings
.disk_clean
= false;
551 /* enter USB mode early, before trying to mount */
552 if (button_get_w_tmo(HZ
/10) == SYS_USB_CONNECTED
)
553 #if (CONFIG_STORAGE & STORAGE_MMC)
554 if (!mmc_touched() ||
555 (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED
))
558 gui_usb_screen_run();
559 mounted
= true; /* mounting done @ end of USB mode */
561 #ifdef HAVE_USB_POWER
562 if (usb_powered()) /* avoid deadlock */
570 CHART(">disk_mount_all");
571 rc
= disk_mount_all();
572 CHART("<disk_mount_all");
576 lcd_puts(0, 0, "No partition");
577 lcd_puts(0, 1, "found.");
578 #ifdef HAVE_LCD_BITMAP
579 lcd_puts(0, 2, "Insert USB cable");
580 lcd_puts(0, 3, "and fix it.");
584 while(button_get(true) != SYS_USB_CONNECTED
) {};
585 gui_usb_screen_run();
590 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
591 (CONFIG_KEYPAD == IRIVER_H10_PAD)
592 #ifdef SETTINGS_RESET
593 /* Reset settings if holding the reset button. (Rec on Archos,
595 if ((button_status() & SETTINGS_RESET
) == SETTINGS_RESET
)
597 /* Reset settings if the hold button is turned on */
601 splash(HZ
*2, str(LANG_RESET_DONE_CLEAR
));
607 CHART(">settings_load(ALL)");
608 settings_load(SETTINGS_ALL
);
609 CHART("<settings_load(ALL)");
612 CHART(">init_dircache(true)");
613 rc
= init_dircache(true);
614 CHART("<init_dircache(true)");
618 remove(TAGCACHE_STATEFILE
);
622 CHART(">settings_apply(true)");
623 settings_apply(true);
624 CHART("<settings_apply(true)");
625 CHART(">init_dircache(false)");
626 init_dircache(false);
627 CHART("<init_dircache(false)");
629 CHART(">init_tagcache");
631 CHART("<init_tagcache");
634 #ifdef HAVE_EEPROM_SETTINGS
635 if (firmware_settings
.initialized
)
637 /* In case we crash. */
638 firmware_settings
.disk_clean
= false;
639 CHART(">eeprom_settings_store");
640 eeprom_settings_store();
641 CHART("<eeprom_settings_store");
648 #if CONFIG_CODEC == SWCODEC
650 #endif /* CONFIG_CODEC == SWCODEC */
652 #if CONFIG_CODEC != SWCODEC
653 /* No buffer allocation (see buffer.c) may take place after the call to
654 audio_init() since the mpeg thread takes the rest of the buffer space */
655 mp3_init( global_settings
.volume
,
656 global_settings
.bass
,
657 global_settings
.treble
,
658 global_settings
.balance
,
659 global_settings
.loudness
,
661 global_settings
.channel_config
,
662 global_settings
.stereo_width
,
663 global_settings
.mdb_strength
,
664 global_settings
.mdb_harmonics
,
665 global_settings
.mdb_center
,
666 global_settings
.mdb_shape
,
667 global_settings
.mdb_enable
,
668 global_settings
.superbass
);
670 /* audio_init must to know the size of voice buffer so init voice first */
672 #endif /* CONFIG_CODEC != SWCODEC */
674 CHART(">audio_init");
676 CHART("<audio_init");
678 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
682 /* runtime database has to be initialized after audio_init() */
686 car_adapter_mode_init();
688 #ifdef IPOD_ACCESSORY_PROTOCOL
689 iap_setup(global_settings
.serial_bitrate
);
691 #ifdef HAVE_ACCESSORY_SUPPLY
692 accessory_supply_set(global_settings
.accessory_supply
);
694 #ifdef HAVE_LINEOUT_POWEROFF
695 lineout_set(global_settings
.lineout_active
);
697 #ifdef HAVE_HOTSWAP_STORAGE_AS_MAIN
698 CHART("<check_bootfile(false)");
699 check_bootfile(false); /* remember write time and filesize */
700 CHART(">check_bootfile(false)");
702 CHART("<settings_apply_skins");
703 settings_apply_skins();
704 CHART(">settings_apply_skins");
708 void __attribute__((noreturn
)) cop_main(void)
710 /* This is the entry point for the coprocessor
711 Anyone not running an upgraded bootloader will never reach this point,
712 so it should not be assumed that the coprocessor be usable even on
713 platforms which support it.
715 A kernel thread is initially setup on the coprocessor and immediately
716 destroyed for purposes of continuity. The cop sits idle until at least
717 one thread exists on it. */
722 /* This should never be reached */
730 #endif /* SIMULATOR */