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"
60 #include "usb_screen.h"
73 #include "eeprom_settings.h"
74 #include "scrobbler.h"
77 #include "statusbar-skinned.h"
78 #include "bootchart.h"
80 #ifdef IPOD_ACCESSORY_PROTOCOL
84 #if (CONFIG_CODEC == SWCODEC)
88 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
89 #include "pcm_record.h"
93 #define SETTINGS_RESET BUTTON_REC
94 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
95 #define SETTINGS_RESET BUTTON_A
101 #if (CONFIG_STORAGE & STORAGE_MMC)
105 #ifdef HAVE_REMOTE_LCD
106 #include "lcd-remote.h"
109 #if CONFIG_USBOTG == USBOTG_ISP1362
113 #if CONFIG_USBOTG == USBOTG_M5636
118 #include "sim_tasks.h"
119 #include "system-sdl.h"
122 /*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
124 const char appsversion
[]=APPSVERSION
;
126 static void init(void);
131 /* main(), and various functions called by main() and init() may be
132 * be INIT_ATTR. These functions must not be called after the final call
133 * to root_menu() at the end of main()
134 * see definition of INIT_ATTR in config.h */
135 int main(void) INIT_ATTR
__attribute__((noreturn
));
145 screens
[i
].clear_display();
148 #ifdef HAVE_LCD_BITMAP
152 /* Keep the order of this 3
153 * Must be done before any code uses the multi-screen API */
155 /* All threads should be created and public queues registered by now */
156 usb_start_monitoring();
161 static const char filename
[] = PLUGIN_APPS_DIR
"/autostart.rock";
163 if(file_exists(filename
)) /* no complaint if it doesn't exist */
165 plugin_load((char*)filename
, NULL
); /* start if it does */
168 #endif /* #ifdef AUTOROCK */
170 global_status
.last_volume_change
= 0;
171 /* no calls INIT_ATTR functions after this point anymore!
172 * see definition of INIT_ATTR in config.h */
177 static int init_dircache(bool preinit
) INIT_ATTR
;
178 static int init_dircache(bool preinit
)
187 if (!global_settings
.dircache
)
190 # ifdef HAVE_EEPROM_SETTINGS
191 if (firmware_settings
.initialized
&& firmware_settings
.disk_clean
194 result
= dircache_load();
198 firmware_settings
.disk_clean
= false;
199 if (global_status
.dircache_size
<= 0)
201 /* This will be in default language, settings are not
202 applied yet. Not really any easy way to fix that. */
203 splash(0, str(LANG_SCANNING_DISK
));
207 dircache_build(global_status
.dircache_size
);
216 if (!dircache_is_enabled()
217 && !dircache_is_initializing())
219 if (global_status
.dircache_size
<= 0)
221 splash(0, str(LANG_SCANNING_DISK
));
224 result
= dircache_build(global_status
.dircache_size
);
229 /* Initialization of dircache failed. Manual action is
230 * necessary to enable dircache again.
232 splashf(0, "Dircache failed, disabled. Result: %d", result
);
233 global_settings
.dircache
= false;
241 global_status
.dircache_size
= dircache_get_cache_size();
253 static void init_tagcache(void) INIT_ATTR
;
254 static void init_tagcache(void)
257 #if CONFIG_CODEC == SWCODEC
258 long talked_tick
= 0;
262 while (!tagcache_is_initialized())
264 int ret
= tagcache_get_commit_step();
268 #if CONFIG_CODEC == SWCODEC
269 /* hwcodec can't use voice here, as the database commit
270 * uses the audio buffer. */
271 if(global_settings
.talk_menu
273 || TIME_AFTER(current_tick
, talked_tick
+7*HZ
)))
275 talked_tick
= current_tick
;
276 talk_id(LANG_TAGCACHE_INIT
, false);
277 talk_number(ret
, true);
278 talk_id(VOICE_OF
, true);
279 talk_number(tagcache_get_max_commit_step(), true);
282 #ifdef HAVE_LCD_BITMAP
285 splashf(0, "[%d/%d] %s", ret
, tagcache_get_max_commit_step(),
286 str(LANG_TAGCACHE_INIT
));
290 splashf(0, "%s [%d/%d]", str(LANG_TAGCACHE_INIT
), ret
,
291 tagcache_get_max_commit_step());
294 lcd_double_height(false);
295 lcd_putsf(0, 1, " DB [%d/%d]", ret
,
296 tagcache_get_max_commit_step());
315 static void init(void)
321 #ifdef HAVE_REMOTE_LCD
329 lang_init(core_language_builtin
, language_strings
,
330 LANG_LAST_INDEX_IN_ARRAY
);
334 /* Keep the order of this 3 (viewportmanager handles statusbars)
335 * Must be done before any code uses the multi-screen API */
336 gui_syncstatusbar_init(&statusbars
);
339 viewportmanager_init();
343 settings_load(SETTINGS_ALL
);
344 settings_apply(true);
346 init_dircache(false);
355 #if CONFIG_CODEC != SWCODEC
356 mp3_init( global_settings
.volume
,
357 global_settings
.bass
,
358 global_settings
.treble
,
359 global_settings
.balance
,
360 global_settings
.loudness
,
362 global_settings
.channel_config
,
363 global_settings
.stereo_width
,
364 global_settings
.mdb_strength
,
365 global_settings
.mdb_harmonics
,
366 global_settings
.mdb_center
,
367 global_settings
.mdb_shape
,
368 global_settings
.mdb_enable
,
369 global_settings
.superbass
);
371 /* audio_init must to know the size of voice buffer so init voice first */
373 #endif /* CONFIG_CODEC != SWCODEC */
376 #if CONFIG_CODEC == SWCODEC
378 #endif /* CONFIG_CODEC == SWCODEC */
381 button_clear_queue(); /* Empty the keyboard buffer */
383 settings_apply_skins();
388 static void init(void) INIT_ATTR
;
389 static void init(void)
392 bool mounted
= false;
393 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
394 /* if nobody initialized ATA before, I consider this a cold start */
395 bool coldstart
= (PACR2
& 0x4000) != 0; /* starting from Flash */
401 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
402 set_cpu_frequency(CPUFREQ_NORMAL
);
404 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS
);
421 /* current_tick should be ticking by now */
425 #ifdef HAVE_REMOTE_LCD
433 lang_init(core_language_builtin
, language_strings
,
434 LANG_LAST_INDEX_IN_ARRAY
);
448 CHART(">settings_load(RTC)");
449 settings_load(SETTINGS_RTC
); /* early load parts of global_settings */
450 CHART("<settings_load(RTC)");
456 #if CONFIG_USBOTG == USBOTG_ISP1362
458 #elif CONFIG_USBOTG == USBOTG_M5636
472 /* Keep the order of this 3 (viewportmanager handles statusbars)
473 * Must be done before any code uses the multi-screen API */
474 CHART(">gui_syncstatusbar_init");
475 gui_syncstatusbar_init(&statusbars
);
476 CHART("<gui_syncstatusbar_init");
477 CHART(">sb_skin_init");
479 CHART("<sb_skin_init");
480 CHART(">gui_sync_wps_init");
482 CHART("<gui_sync_wps_init");
483 CHART(">viewportmanager_init");
484 viewportmanager_init();
485 CHART("<viewportmanager_init");
487 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
488 /* charger_inserted() can't be used here because power_thread()
489 hasn't checked power_input_status() yet */
490 if (coldstart
&& (power_input_status() & POWER_INPUT_MAIN_CHARGER
)
491 && !global_settings
.car_adapter_mode
492 #ifdef ATA_POWER_PLAYERSTYLE
493 && !ide_powered() /* relies on probing result from bootloader */
497 rc
= charging_screen(); /* display a "charging" screen */
498 if (rc
== 1) /* charger removed */
500 /* "On" pressed or USB connected: proceed */
501 show_logo(); /* again, to provide better visual feedback */
505 CHART(">storage_init");
507 CHART("<storage_init");
510 #ifdef HAVE_LCD_BITMAP
512 lcd_putsf(0, 1, "ATA error: %d", rc
);
513 lcd_puts(0, 3, "Press ON to debug");
515 while(!(button_get(true) & BUTTON_REL
)); /*DO NOT CHANGE TO ACTION SYSTEM */
518 panicf("ata: %d", rc
);
521 #ifdef HAVE_EEPROM_SETTINGS
522 CHART(">eeprom_settings_init");
523 eeprom_settings_init();
524 CHART("<eeprom_settings_init");
527 #ifndef HAVE_USBSTACK
528 usb_start_monitoring();
529 while (usb_detect() == USB_INSERTED
)
531 #ifdef HAVE_EEPROM_SETTINGS
532 firmware_settings
.disk_clean
= false;
534 /* enter USB mode early, before trying to mount */
535 if (button_get_w_tmo(HZ
/10) == SYS_USB_CONNECTED
)
536 #if (CONFIG_STORAGE & STORAGE_MMC)
537 if (!mmc_touched() ||
538 (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED
))
541 gui_usb_screen_run();
542 mounted
= true; /* mounting done @ end of USB mode */
544 #ifdef HAVE_USB_POWER
545 if (usb_powered()) /* avoid deadlock */
553 CHART(">disk_mount_all");
554 rc
= disk_mount_all();
555 CHART("<disk_mount_all");
559 lcd_puts(0, 0, "No partition");
560 lcd_puts(0, 1, "found.");
561 #ifdef HAVE_LCD_BITMAP
562 lcd_puts(0, 2, "Insert USB cable");
563 lcd_puts(0, 3, "and fix it.");
567 while(button_get(true) != SYS_USB_CONNECTED
) {};
568 gui_usb_screen_run();
573 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
574 (CONFIG_KEYPAD == IRIVER_H10_PAD)
575 #ifdef SETTINGS_RESET
576 /* Reset settings if holding the reset button. (Rec on Archos,
578 if ((button_status() & SETTINGS_RESET
) == SETTINGS_RESET
)
580 /* Reset settings if the hold button is turned on */
584 splash(HZ
*2, str(LANG_RESET_DONE_CLEAR
));
590 CHART(">settings_load(ALL)");
591 settings_load(SETTINGS_ALL
);
592 CHART("<settings_load(ALL)");
595 CHART(">init_dircache(true)");
596 rc
= init_dircache(true);
597 CHART("<init_dircache(true)");
601 remove(TAGCACHE_STATEFILE
);
605 CHART(">settings_apply(true)");
606 settings_apply(true);
607 CHART("<settings_apply(true)");
608 CHART(">init_dircache(false)");
609 init_dircache(false);
610 CHART("<init_dircache(false)");
612 CHART(">init_tagcache");
614 CHART("<init_tagcache");
617 #ifdef HAVE_EEPROM_SETTINGS
618 if (firmware_settings
.initialized
)
620 /* In case we crash. */
621 firmware_settings
.disk_clean
= false;
622 CHART(">eeprom_settings_store");
623 eeprom_settings_store();
624 CHART("<eeprom_settings_store");
631 #if CONFIG_CODEC == SWCODEC
633 #endif /* CONFIG_CODEC == SWCODEC */
635 #if CONFIG_CODEC != SWCODEC
636 /* No buffer allocation (see buffer.c) may take place after the call to
637 audio_init() since the mpeg thread takes the rest of the buffer space */
638 mp3_init( global_settings
.volume
,
639 global_settings
.bass
,
640 global_settings
.treble
,
641 global_settings
.balance
,
642 global_settings
.loudness
,
644 global_settings
.channel_config
,
645 global_settings
.stereo_width
,
646 global_settings
.mdb_strength
,
647 global_settings
.mdb_harmonics
,
648 global_settings
.mdb_center
,
649 global_settings
.mdb_shape
,
650 global_settings
.mdb_enable
,
651 global_settings
.superbass
);
653 /* audio_init must to know the size of voice buffer so init voice first */
655 #endif /* CONFIG_CODEC != SWCODEC */
657 CHART(">audio_init");
659 CHART("<audio_init");
661 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
665 /* runtime database has to be initialized after audio_init() */
669 car_adapter_mode_init();
671 #ifdef IPOD_ACCESSORY_PROTOCOL
672 iap_setup(global_settings
.serial_bitrate
);
674 #ifdef HAVE_ACCESSORY_SUPPLY
675 accessory_supply_set(global_settings
.accessory_supply
);
677 #ifdef HAVE_LINEOUT_POWEROFF
678 lineout_set(global_settings
.lineout_active
);
680 #ifdef HAVE_HOTSWAP_STORAGE_AS_MAIN
681 CHART("<check_bootfile(false)");
682 check_bootfile(false); /* remember write time and filesize */
683 CHART(">check_bootfile(false)");
685 CHART("<settings_apply_skins");
686 settings_apply_skins();
687 CHART(">settings_apply_skins");
693 /* This is the entry point for the coprocessor
694 Anyone not running an upgraded bootloader will never reach this point,
695 so it should not be assumed that the coprocessor be usable even on
696 platforms which support it.
698 A kernel thread is initially setup on the coprocessor and immediately
699 destroyed for purposes of continuity. The cop sits idle until at least
700 one thread exists on it. */
702 /* 3G doesn't have Rolo or dual core support yet */
706 /* This should never be reached */