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 const char appsversion
[]=APPSVERSION
;
125 static void init(void);
130 /* main(), and various functions called by main() and init() may be
131 * be INIT_ATTR. These functions must not be called after the final call
132 * to root_menu() at the end of main()
133 * see definition of INIT_ATTR in config.h */
134 int main(void) INIT_ATTR
__attribute__((noreturn
));
144 screens
[i
].clear_display();
147 #ifdef HAVE_LCD_BITMAP
151 /* Keep the order of this 3
152 * Must be done before any code uses the multi-screen API */
154 /* All threads should be created and public queues registered by now */
155 usb_start_monitoring();
160 static const char filename
[] = PLUGIN_APPS_DIR
"/autostart.rock";
162 if(file_exists(filename
)) /* no complaint if it doesn't exist */
164 plugin_load((char*)filename
, NULL
); /* start if it does */
167 #endif /* #ifdef AUTOROCK */
169 global_status
.last_volume_change
= 0;
170 /* no calls INIT_ATTR functions after this point anymore!
171 * see definition of INIT_ATTR in config.h */
176 static int init_dircache(bool preinit
) INIT_ATTR
;
177 static int init_dircache(bool preinit
)
186 if (!global_settings
.dircache
)
189 # ifdef HAVE_EEPROM_SETTINGS
190 if (firmware_settings
.initialized
&& firmware_settings
.disk_clean
193 result
= dircache_load();
197 firmware_settings
.disk_clean
= false;
198 if (global_status
.dircache_size
<= 0)
200 /* This will be in default language, settings are not
201 applied yet. Not really any easy way to fix that. */
202 splash(0, str(LANG_SCANNING_DISK
));
206 dircache_build(global_status
.dircache_size
);
215 if (!dircache_is_enabled()
216 && !dircache_is_initializing())
218 if (global_status
.dircache_size
<= 0)
220 splash(0, str(LANG_SCANNING_DISK
));
223 result
= dircache_build(global_status
.dircache_size
);
228 /* Initialization of dircache failed. Manual action is
229 * necessary to enable dircache again.
231 splashf(0, "Dircache failed, disabled. Result: %d", result
);
232 global_settings
.dircache
= false;
240 global_status
.dircache_size
= dircache_get_cache_size();
252 static void init_tagcache(void) INIT_ATTR
;
253 static void init_tagcache(void)
256 #if CONFIG_CODEC == SWCODEC
257 long talked_tick
= 0;
261 while (!tagcache_is_initialized())
263 int ret
= tagcache_get_commit_step();
267 #if CONFIG_CODEC == SWCODEC
268 /* hwcodec can't use voice here, as the database commit
269 * uses the audio buffer. */
270 if(global_settings
.talk_menu
272 || TIME_AFTER(current_tick
, talked_tick
+7*HZ
)))
274 talked_tick
= current_tick
;
275 talk_id(LANG_TAGCACHE_INIT
, false);
276 talk_number(ret
, true);
277 talk_id(VOICE_OF
, true);
278 talk_number(tagcache_get_max_commit_step(), true);
281 #ifdef HAVE_LCD_BITMAP
284 splashf(0, "[%d/%d] %s", ret
, tagcache_get_max_commit_step(),
285 str(LANG_TAGCACHE_INIT
));
289 splashf(0, "%s [%d/%d]", str(LANG_TAGCACHE_INIT
), ret
,
290 tagcache_get_max_commit_step());
293 lcd_double_height(false);
294 lcd_putsf(0, 1, " DB [%d/%d]", ret
,
295 tagcache_get_max_commit_step());
314 static void init(void)
320 #ifdef HAVE_REMOTE_LCD
328 lang_init(core_language_builtin
, language_strings
,
329 LANG_LAST_INDEX_IN_ARRAY
);
333 /* Keep the order of this 3 (viewportmanager handles statusbars)
334 * Must be done before any code uses the multi-screen API */
335 gui_syncstatusbar_init(&statusbars
);
338 viewportmanager_init();
342 settings_load(SETTINGS_ALL
);
343 settings_apply(true);
345 init_dircache(false);
354 #if CONFIG_CODEC != SWCODEC
355 mp3_init( global_settings
.volume
,
356 global_settings
.bass
,
357 global_settings
.treble
,
358 global_settings
.balance
,
359 global_settings
.loudness
,
361 global_settings
.channel_config
,
362 global_settings
.stereo_width
,
363 global_settings
.mdb_strength
,
364 global_settings
.mdb_harmonics
,
365 global_settings
.mdb_center
,
366 global_settings
.mdb_shape
,
367 global_settings
.mdb_enable
,
368 global_settings
.superbass
);
370 /* audio_init must to know the size of voice buffer so init voice first */
372 #endif /* CONFIG_CODEC != SWCODEC */
375 #if CONFIG_CODEC == SWCODEC
377 #endif /* CONFIG_CODEC == SWCODEC */
380 button_clear_queue(); /* Empty the keyboard buffer */
382 settings_apply_skins();
387 static void init(void) INIT_ATTR
;
388 static void init(void)
391 bool mounted
= false;
392 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
393 /* if nobody initialized ATA before, I consider this a cold start */
394 bool coldstart
= (PACR2
& 0x4000) != 0; /* starting from Flash */
400 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
401 set_cpu_frequency(CPUFREQ_NORMAL
);
403 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS
);
420 /* current_tick should be ticking by now */
424 #ifdef HAVE_REMOTE_LCD
432 lang_init(core_language_builtin
, language_strings
,
433 LANG_LAST_INDEX_IN_ARRAY
);
447 CHART(">settings_load(RTC)");
448 settings_load(SETTINGS_RTC
); /* early load parts of global_settings */
449 CHART("<settings_load(RTC)");
455 #if CONFIG_USBOTG == USBOTG_ISP1362
457 #elif CONFIG_USBOTG == USBOTG_M5636
471 /* Keep the order of this 3 (viewportmanager handles statusbars)
472 * Must be done before any code uses the multi-screen API */
473 CHART(">gui_syncstatusbar_init");
474 gui_syncstatusbar_init(&statusbars
);
475 CHART("<gui_syncstatusbar_init");
476 CHART(">sb_skin_init");
478 CHART("<sb_skin_init");
479 CHART(">gui_sync_wps_init");
481 CHART("<gui_sync_wps_init");
482 CHART(">viewportmanager_init");
483 viewportmanager_init();
484 CHART("<viewportmanager_init");
486 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
487 /* charger_inserted() can't be used here because power_thread()
488 hasn't checked power_input_status() yet */
489 if (coldstart
&& (power_input_status() & POWER_INPUT_MAIN_CHARGER
)
490 && !global_settings
.car_adapter_mode
491 #ifdef ATA_POWER_PLAYERSTYLE
492 && !ide_powered() /* relies on probing result from bootloader */
496 rc
= charging_screen(); /* display a "charging" screen */
497 if (rc
== 1) /* charger removed */
499 /* "On" pressed or USB connected: proceed */
500 show_logo(); /* again, to provide better visual feedback */
504 CHART(">storage_init");
506 CHART("<storage_init");
509 #ifdef HAVE_LCD_BITMAP
511 lcd_putsf(0, 1, "ATA error: %d", rc
);
512 lcd_puts(0, 3, "Press ON to debug");
514 while(!(button_get(true) & BUTTON_REL
)); /*DO NOT CHANGE TO ACTION SYSTEM */
517 panicf("ata: %d", rc
);
520 #ifdef HAVE_EEPROM_SETTINGS
521 CHART(">eeprom_settings_init");
522 eeprom_settings_init();
523 CHART("<eeprom_settings_init");
526 #ifndef HAVE_USBSTACK
527 usb_start_monitoring();
528 while (usb_detect() == USB_INSERTED
)
530 #ifdef HAVE_EEPROM_SETTINGS
531 firmware_settings
.disk_clean
= false;
533 /* enter USB mode early, before trying to mount */
534 if (button_get_w_tmo(HZ
/10) == SYS_USB_CONNECTED
)
535 #if (CONFIG_STORAGE & STORAGE_MMC)
536 if (!mmc_touched() ||
537 (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED
))
540 gui_usb_screen_run();
541 mounted
= true; /* mounting done @ end of USB mode */
543 #ifdef HAVE_USB_POWER
544 if (usb_powered()) /* avoid deadlock */
552 CHART(">disk_mount_all");
553 rc
= disk_mount_all();
554 CHART("<disk_mount_all");
558 lcd_puts(0, 0, "No partition");
559 lcd_puts(0, 1, "found.");
560 #ifdef HAVE_LCD_BITMAP
561 lcd_puts(0, 2, "Insert USB cable");
562 lcd_puts(0, 3, "and fix it.");
566 while(button_get(true) != SYS_USB_CONNECTED
) {};
567 gui_usb_screen_run();
572 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
573 (CONFIG_KEYPAD == IRIVER_H10_PAD)
574 #ifdef SETTINGS_RESET
575 /* Reset settings if holding the reset button. (Rec on Archos,
577 if ((button_status() & SETTINGS_RESET
) == SETTINGS_RESET
)
579 /* Reset settings if the hold button is turned on */
583 splash(HZ
*2, str(LANG_RESET_DONE_CLEAR
));
589 CHART(">settings_load(ALL)");
590 settings_load(SETTINGS_ALL
);
591 CHART("<settings_load(ALL)");
594 CHART(">init_dircache(true)");
595 rc
= init_dircache(true);
596 CHART("<init_dircache(true)");
600 remove(TAGCACHE_STATEFILE
);
604 CHART(">settings_apply(true)");
605 settings_apply(true);
606 CHART("<settings_apply(true)");
607 CHART(">init_dircache(false)");
608 init_dircache(false);
609 CHART("<init_dircache(false)");
611 CHART(">init_tagcache");
613 CHART("<init_tagcache");
616 #ifdef HAVE_EEPROM_SETTINGS
617 if (firmware_settings
.initialized
)
619 /* In case we crash. */
620 firmware_settings
.disk_clean
= false;
621 CHART(">eeprom_settings_store");
622 eeprom_settings_store();
623 CHART("<eeprom_settings_store");
630 #if CONFIG_CODEC == SWCODEC
632 #endif /* CONFIG_CODEC == SWCODEC */
634 #if CONFIG_CODEC != SWCODEC
635 /* No buffer allocation (see buffer.c) may take place after the call to
636 audio_init() since the mpeg thread takes the rest of the buffer space */
637 mp3_init( global_settings
.volume
,
638 global_settings
.bass
,
639 global_settings
.treble
,
640 global_settings
.balance
,
641 global_settings
.loudness
,
643 global_settings
.channel_config
,
644 global_settings
.stereo_width
,
645 global_settings
.mdb_strength
,
646 global_settings
.mdb_harmonics
,
647 global_settings
.mdb_center
,
648 global_settings
.mdb_shape
,
649 global_settings
.mdb_enable
,
650 global_settings
.superbass
);
652 /* audio_init must to know the size of voice buffer so init voice first */
654 #endif /* CONFIG_CODEC != SWCODEC */
656 CHART(">audio_init");
658 CHART("<audio_init");
660 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
664 /* runtime database has to be initialized after audio_init() */
668 car_adapter_mode_init();
670 #ifdef IPOD_ACCESSORY_PROTOCOL
671 iap_setup(global_settings
.serial_bitrate
);
673 #ifdef HAVE_ACCESSORY_SUPPLY
674 accessory_supply_set(global_settings
.accessory_supply
);
676 #ifdef HAVE_LINEOUT_POWEROFF
677 lineout_set(global_settings
.lineout_active
);
679 #ifdef HAVE_HOTSWAP_STORAGE_AS_MAIN
680 CHART("<check_bootfile(false)");
681 check_bootfile(false); /* remember write time and filesize */
682 CHART(">check_bootfile(false)");
684 CHART("<settings_apply_skins");
685 settings_apply_skins();
686 CHART(">settings_apply_skins");
692 /* This is the entry point for the coprocessor
693 Anyone not running an upgraded bootloader will never reach this point,
694 so it should not be assumed that the coprocessor be usable even on
695 platforms which support it.
697 A kernel thread is initially setup on the coprocessor and immediately
698 destroyed for purposes of continuity. The cop sits idle until at least
699 one thread exists on it. */
701 /* 3G doesn't have Rolo or dual core support yet */
705 /* This should never be reached */