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"
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
[])
134 sys_handle_argv(argc
, argv
);
136 /* main(), and various functions called by main() and init() may be
137 * be INIT_ATTR. These functions must not be called after the final call
138 * to root_menu() at the end of main()
139 * see definition of INIT_ATTR in config.h */
140 int main(void) INIT_ATTR
__attribute__((noreturn
));
150 screens
[i
].clear_display();
153 #ifdef HAVE_LCD_BITMAP
157 /* Keep the order of this 3
158 * Must be done before any code uses the multi-screen API */
160 /* All threads should be created and public queues registered by now */
161 usb_start_monitoring();
166 static const char filename
[] = PLUGIN_APPS_DIR
"/autostart.rock";
168 if(file_exists(filename
)) /* no complaint if it doesn't exist */
170 plugin_load((char*)filename
, NULL
); /* start if it does */
173 #endif /* #ifdef AUTOROCK */
175 global_status
.last_volume_change
= 0;
176 /* no calls INIT_ATTR functions after this point anymore!
177 * see definition of INIT_ATTR in config.h */
182 static int init_dircache(bool preinit
) INIT_ATTR
;
183 static int init_dircache(bool preinit
)
192 if (!global_settings
.dircache
)
195 # ifdef HAVE_EEPROM_SETTINGS
196 if (firmware_settings
.initialized
&& firmware_settings
.disk_clean
199 result
= dircache_load();
203 firmware_settings
.disk_clean
= false;
204 if (global_status
.dircache_size
<= 0)
206 /* This will be in default language, settings are not
207 applied yet. Not really any easy way to fix that. */
208 splash(0, str(LANG_SCANNING_DISK
));
212 dircache_build(global_status
.dircache_size
);
221 if (!dircache_is_enabled()
222 && !dircache_is_initializing())
224 if (global_status
.dircache_size
<= 0)
226 splash(0, str(LANG_SCANNING_DISK
));
229 result
= dircache_build(global_status
.dircache_size
);
234 /* Initialization of dircache failed. Manual action is
235 * necessary to enable dircache again.
237 splashf(0, "Dircache failed, disabled. Result: %d", result
);
238 global_settings
.dircache
= false;
246 global_status
.dircache_size
= dircache_get_cache_size();
258 static void init_tagcache(void) INIT_ATTR
;
259 static void init_tagcache(void)
262 #if CONFIG_CODEC == SWCODEC
263 long talked_tick
= 0;
267 while (!tagcache_is_initialized())
269 int ret
= tagcache_get_commit_step();
273 #if CONFIG_CODEC == SWCODEC
274 /* hwcodec can't use voice here, as the database commit
275 * uses the audio buffer. */
276 if(global_settings
.talk_menu
278 || TIME_AFTER(current_tick
, talked_tick
+7*HZ
)))
280 talked_tick
= current_tick
;
281 talk_id(LANG_TAGCACHE_INIT
, false);
282 talk_number(ret
, true);
283 talk_id(VOICE_OF
, true);
284 talk_number(tagcache_get_max_commit_step(), true);
287 #ifdef HAVE_LCD_BITMAP
290 splashf(0, "[%d/%d] %s", ret
, tagcache_get_max_commit_step(),
291 str(LANG_TAGCACHE_INIT
));
295 splashf(0, "%s [%d/%d]", str(LANG_TAGCACHE_INIT
), ret
,
296 tagcache_get_max_commit_step());
299 lcd_double_height(false);
300 lcd_putsf(0, 1, " DB [%d/%d]", ret
,
301 tagcache_get_max_commit_step());
318 #if (CONFIG_PLATFORM & PLATFORM_HOSTED)
320 static void init(void)
327 #ifdef HAVE_REMOTE_LCD
335 lang_init(core_language_builtin
, language_strings
,
336 LANG_LAST_INDEX_IN_ARRAY
);
340 /* Keep the order of this 3 (viewportmanager handles statusbars)
341 * Must be done before any code uses the multi-screen API */
342 gui_syncstatusbar_init(&statusbars
);
345 viewportmanager_init();
349 settings_load(SETTINGS_ALL
);
350 settings_apply(true);
352 init_dircache(false);
361 #if CONFIG_CODEC != SWCODEC
362 mp3_init( global_settings
.volume
,
363 global_settings
.bass
,
364 global_settings
.treble
,
365 global_settings
.balance
,
366 global_settings
.loudness
,
368 global_settings
.channel_config
,
369 global_settings
.stereo_width
,
370 global_settings
.mdb_strength
,
371 global_settings
.mdb_harmonics
,
372 global_settings
.mdb_center
,
373 global_settings
.mdb_shape
,
374 global_settings
.mdb_enable
,
375 global_settings
.superbass
);
377 /* audio_init must to know the size of voice buffer so init voice first */
379 #endif /* CONFIG_CODEC != SWCODEC */
382 #if CONFIG_CODEC == SWCODEC
384 #endif /* CONFIG_CODEC == SWCODEC */
387 button_clear_queue(); /* Empty the keyboard buffer */
389 settings_apply_skins();
394 static void init(void) INIT_ATTR
;
395 static void init(void)
398 bool mounted
= false;
399 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
400 /* if nobody initialized ATA before, I consider this a cold start */
401 bool coldstart
= (PACR2
& 0x4000) != 0; /* starting from Flash */
407 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
408 set_cpu_frequency(CPUFREQ_NORMAL
);
410 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS
);
427 /* current_tick should be ticking by now */
431 #ifdef HAVE_REMOTE_LCD
439 lang_init(core_language_builtin
, language_strings
,
440 LANG_LAST_INDEX_IN_ARRAY
);
454 CHART(">settings_load(RTC)");
455 settings_load(SETTINGS_RTC
); /* early load parts of global_settings */
456 CHART("<settings_load(RTC)");
462 #if CONFIG_USBOTG == USBOTG_ISP1362
464 #elif CONFIG_USBOTG == USBOTG_M5636
478 /* Keep the order of this 3 (viewportmanager handles statusbars)
479 * Must be done before any code uses the multi-screen API */
480 CHART(">gui_syncstatusbar_init");
481 gui_syncstatusbar_init(&statusbars
);
482 CHART("<gui_syncstatusbar_init");
483 CHART(">sb_skin_init");
485 CHART("<sb_skin_init");
486 CHART(">gui_sync_wps_init");
488 CHART("<gui_sync_wps_init");
489 CHART(">viewportmanager_init");
490 viewportmanager_init();
491 CHART("<viewportmanager_init");
493 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
494 /* charger_inserted() can't be used here because power_thread()
495 hasn't checked power_input_status() yet */
496 if (coldstart
&& (power_input_status() & POWER_INPUT_MAIN_CHARGER
)
497 && !global_settings
.car_adapter_mode
498 #ifdef ATA_POWER_PLAYERSTYLE
499 && !ide_powered() /* relies on probing result from bootloader */
503 rc
= charging_screen(); /* display a "charging" screen */
504 if (rc
== 1) /* charger removed */
506 /* "On" pressed or USB connected: proceed */
507 show_logo(); /* again, to provide better visual feedback */
512 disk_init_subsystem();
513 CHART(">storage_init");
515 CHART("<storage_init");
518 #ifdef HAVE_LCD_BITMAP
520 lcd_putsf(0, 1, "ATA error: %d", rc
);
521 lcd_puts(0, 3, "Press ON to debug");
523 while(!(button_get(true) & BUTTON_REL
)); /*DO NOT CHANGE TO ACTION SYSTEM */
526 panicf("ata: %d", rc
);
529 #ifdef HAVE_EEPROM_SETTINGS
530 CHART(">eeprom_settings_init");
531 eeprom_settings_init();
532 CHART("<eeprom_settings_init");
535 #ifndef HAVE_USBSTACK
536 usb_start_monitoring();
537 while (usb_detect() == USB_INSERTED
)
539 #ifdef HAVE_EEPROM_SETTINGS
540 firmware_settings
.disk_clean
= false;
542 /* enter USB mode early, before trying to mount */
543 if (button_get_w_tmo(HZ
/10) == SYS_USB_CONNECTED
)
544 #if (CONFIG_STORAGE & STORAGE_MMC)
545 if (!mmc_touched() ||
546 (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED
))
549 gui_usb_screen_run();
550 mounted
= true; /* mounting done @ end of USB mode */
552 #ifdef HAVE_USB_POWER
553 if (usb_powered()) /* avoid deadlock */
561 CHART(">disk_mount_all");
562 rc
= disk_mount_all();
563 CHART("<disk_mount_all");
567 lcd_puts(0, 0, "No partition");
568 lcd_puts(0, 1, "found.");
569 #ifdef HAVE_LCD_BITMAP
570 lcd_puts(0, 2, "Insert USB cable");
571 lcd_puts(0, 3, "and fix it.");
575 while(button_get(true) != SYS_USB_CONNECTED
) {};
576 gui_usb_screen_run();
581 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
582 (CONFIG_KEYPAD == IRIVER_H10_PAD)
583 #ifdef SETTINGS_RESET
584 /* Reset settings if holding the reset button. (Rec on Archos,
586 if ((button_status() & SETTINGS_RESET
) == SETTINGS_RESET
)
588 /* Reset settings if the hold button is turned on */
592 splash(HZ
*2, str(LANG_RESET_DONE_CLEAR
));
598 CHART(">settings_load(ALL)");
599 settings_load(SETTINGS_ALL
);
600 CHART("<settings_load(ALL)");
603 CHART(">init_dircache(true)");
604 rc
= init_dircache(true);
605 CHART("<init_dircache(true)");
609 remove(TAGCACHE_STATEFILE
);
613 CHART(">settings_apply(true)");
614 settings_apply(true);
615 CHART("<settings_apply(true)");
616 CHART(">init_dircache(false)");
617 init_dircache(false);
618 CHART("<init_dircache(false)");
620 CHART(">init_tagcache");
622 CHART("<init_tagcache");
625 #ifdef HAVE_EEPROM_SETTINGS
626 if (firmware_settings
.initialized
)
628 /* In case we crash. */
629 firmware_settings
.disk_clean
= false;
630 CHART(">eeprom_settings_store");
631 eeprom_settings_store();
632 CHART("<eeprom_settings_store");
639 #if CONFIG_CODEC == SWCODEC
641 #endif /* CONFIG_CODEC == SWCODEC */
643 #if CONFIG_CODEC != SWCODEC
644 /* No buffer allocation (see buffer.c) may take place after the call to
645 audio_init() since the mpeg thread takes the rest of the buffer space */
646 mp3_init( global_settings
.volume
,
647 global_settings
.bass
,
648 global_settings
.treble
,
649 global_settings
.balance
,
650 global_settings
.loudness
,
652 global_settings
.channel_config
,
653 global_settings
.stereo_width
,
654 global_settings
.mdb_strength
,
655 global_settings
.mdb_harmonics
,
656 global_settings
.mdb_center
,
657 global_settings
.mdb_shape
,
658 global_settings
.mdb_enable
,
659 global_settings
.superbass
);
661 /* audio_init must to know the size of voice buffer so init voice first */
663 #endif /* CONFIG_CODEC != SWCODEC */
665 CHART(">audio_init");
667 CHART("<audio_init");
669 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
673 /* runtime database has to be initialized after audio_init() */
677 car_adapter_mode_init();
679 #ifdef IPOD_ACCESSORY_PROTOCOL
680 iap_setup(global_settings
.serial_bitrate
);
682 #ifdef HAVE_ACCESSORY_SUPPLY
683 accessory_supply_set(global_settings
.accessory_supply
);
685 #ifdef HAVE_LINEOUT_POWEROFF
686 lineout_set(global_settings
.lineout_active
);
688 #ifdef HAVE_HOTSWAP_STORAGE_AS_MAIN
689 CHART("<check_bootfile(false)");
690 check_bootfile(false); /* remember write time and filesize */
691 CHART(">check_bootfile(false)");
693 CHART("<settings_apply_skins");
694 settings_apply_skins();
695 CHART(">settings_apply_skins");
699 void __attribute__((noreturn
)) cop_main(void)
701 /* This is the entry point for the coprocessor
702 Anyone not running an upgraded bootloader will never reach this point,
703 so it should not be assumed that the coprocessor be usable even on
704 platforms which support it.
706 A kernel thread is initially setup on the coprocessor and immediately
707 destroyed for purposes of continuity. The cop sits idle until at least
708 one thread exists on it. */
713 /* This should never be reached */
721 #endif /* SIMULATOR */