haloween night is when red monsters are vanquished right? or is that green monsters?
[kugel-rb.git] / apps / main.c
blob677eeb5b21946790dcaa48fef3a5e74e1268b636
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
21 #include "config.h"
23 #include "storage.h"
24 #include "disk.h"
25 #include "fat.h"
26 #include "lcd.h"
27 #include "rtc.h"
28 #include "debug.h"
29 #include "led.h"
30 #include "kernel.h"
31 #include "button.h"
32 #include "tree.h"
33 #include "filetypes.h"
34 #include "panic.h"
35 #include "menu.h"
36 #include "system.h"
37 #include "usb.h"
38 #include "powermgmt.h"
39 #include "adc.h"
40 #include "i2c.h"
41 #ifndef DEBUG
42 #include "serial.h"
43 #endif
44 #include "audio.h"
45 #include "mp3_playback.h"
46 #include "thread.h"
47 #include "settings.h"
48 #include "backlight.h"
49 #include "status.h"
50 #include "debug_menu.h"
51 #include "version.h"
52 #include "sprintf.h"
53 #include "font.h"
54 #include "language.h"
55 #include "wps.h"
56 #include "playlist.h"
57 #include "buffer.h"
58 #include "rolo.h"
59 #include "screens.h"
60 #include "usb_screen.h"
61 #include "power.h"
62 #include "talk.h"
63 #include "plugin.h"
64 #include "misc.h"
65 #include "dircache.h"
66 #ifdef HAVE_TAGCACHE
67 #include "tagcache.h"
68 #include "tagtree.h"
69 #endif
70 #include "lang.h"
71 #include "string.h"
72 #include "splash.h"
73 #include "eeprom_settings.h"
74 #include "scrobbler.h"
75 #include "icon.h"
76 #include "viewport.h"
77 #include "statusbar-skinned.h"
79 #ifdef IPOD_ACCESSORY_PROTOCOL
80 #include "iap.h"
81 #endif
83 #if (CONFIG_CODEC == SWCODEC)
84 #include "playback.h"
85 #include "tdspeed.h"
86 #endif
87 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
88 #include "pcm_record.h"
89 #endif
91 #ifdef BUTTON_REC
92 #define SETTINGS_RESET BUTTON_REC
93 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
94 #define SETTINGS_RESET BUTTON_A
95 #endif
97 #if CONFIG_TUNER
98 #include "radio.h"
99 #endif
100 #if (CONFIG_STORAGE & STORAGE_MMC)
101 #include "ata_mmc.h"
102 #endif
104 #ifdef HAVE_REMOTE_LCD
105 #include "lcd-remote.h"
106 #endif
108 #if CONFIG_USBOTG == USBOTG_ISP1362
109 #include "isp1362.h"
110 #endif
112 #if CONFIG_USBOTG == USBOTG_M5636
113 #include "m5636.h"
114 #endif
116 #ifdef SIMULATOR
117 #include "sim_tasks.h"
118 #include "system-sdl.h"
119 #endif
121 /*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
123 const char appsversion[]=APPSVERSION;
125 static void init(void);
127 #ifdef SIMULATOR
128 void app_main(void)
129 #else
130 static void app_main(void)
131 #endif
133 int i;
134 init();
135 FOR_NB_SCREENS(i)
137 screens[i].clear_display();
138 screens[i].update();
140 #ifdef HAVE_LCD_BITMAP
141 list_init();
142 #endif
143 tree_gui_init();
144 viewportmanager_init();
145 #ifdef HAVE_USBSTACK
146 /* All threads should be created and public queues registered by now */
147 usb_start_monitoring();
148 #endif
150 #ifdef AUTOROCK
152 static const char filename[] = PLUGIN_APPS_DIR "/autostart.rock";
154 if(file_exists(filename)) /* no complaint if it doesn't exist */
156 plugin_load((char*)filename, NULL); /* start if it does */
159 #endif /* #ifdef AUTOROCK */
161 global_status.last_volume_change = 0;
162 root_menu();
165 static int init_dircache(bool preinit)
167 #ifdef HAVE_DIRCACHE
168 int result = 0;
169 bool clear = false;
171 if (preinit)
172 dircache_init();
174 if (!global_settings.dircache)
175 return 0;
177 # ifdef HAVE_EEPROM_SETTINGS
178 if (firmware_settings.initialized && firmware_settings.disk_clean
179 && preinit)
181 result = dircache_load();
183 if (result < 0)
185 firmware_settings.disk_clean = false;
186 if (global_status.dircache_size <= 0)
188 /* This will be in default language, settings are not
189 applied yet. Not really any easy way to fix that. */
190 splash(0, str(LANG_SCANNING_DISK));
191 clear = true;
194 dircache_build(global_status.dircache_size);
197 else
198 # endif
200 if (preinit)
201 return -1;
203 if (!dircache_is_enabled()
204 && !dircache_is_initializing())
206 if (global_status.dircache_size <= 0)
208 splash(0, str(LANG_SCANNING_DISK));
209 clear = true;
211 result = dircache_build(global_status.dircache_size);
214 if (result < 0)
216 /* Initialization of dircache failed. Manual action is
217 * necessary to enable dircache again.
219 splashf(0, "Dircache failed, disabled. Result: %d", result);
220 global_settings.dircache = false;
224 if (clear)
226 backlight_on();
227 show_logo();
228 global_status.dircache_size = dircache_get_cache_size();
229 status_save();
232 return result;
233 #else
234 (void)preinit;
235 return 0;
236 #endif
239 #ifdef HAVE_TAGCACHE
240 static void init_tagcache(void)
242 bool clear = false;
243 #if CONFIG_CODEC == SWCODEC
244 long talked_tick = 0;
245 #endif
246 tagcache_init();
248 while (!tagcache_is_initialized())
250 int ret = tagcache_get_commit_step();
252 if (ret > 0)
254 #if CONFIG_CODEC == SWCODEC
255 /* hwcodec can't use voice here, as the database commit
256 * uses the audio buffer. */
257 if(global_settings.talk_menu
258 && (talked_tick == 0
259 || TIME_AFTER(current_tick, talked_tick+7*HZ)))
261 talked_tick = current_tick;
262 talk_id(LANG_TAGCACHE_INIT, false);
263 talk_number(ret, true);
264 talk_id(VOICE_OF, true);
265 talk_number(tagcache_get_max_commit_step(), true);
267 #endif
268 #ifdef HAVE_LCD_BITMAP
269 if (lang_is_rtl())
271 splashf(0, "[%d/%d] %s", ret, tagcache_get_max_commit_step(),
272 str(LANG_TAGCACHE_INIT));
274 else
276 splashf(0, "%s [%d/%d]", str(LANG_TAGCACHE_INIT), ret,
277 tagcache_get_max_commit_step());
279 #else
280 lcd_double_height(false);
281 lcd_putsf(0, 1, " DB [%d/%d]", ret,
282 tagcache_get_max_commit_step());
283 lcd_update();
284 #endif
285 clear = true;
287 sleep(HZ/4);
289 tagtree_init();
291 if (clear)
293 backlight_on();
294 show_logo();
297 #endif
299 #ifdef SIMULATOR
301 static void init(void)
303 kernel_init();
304 buffer_init();
305 enable_irq();
306 lcd_init();
307 #ifdef HAVE_REMOTE_LCD
308 lcd_remote_init();
309 #endif
310 font_init();
311 show_logo();
312 button_init();
313 backlight_init();
314 sim_tasks_init();
315 lang_init(core_language_builtin, language_strings,
316 LANG_LAST_INDEX_IN_ARRAY);
317 #ifdef DEBUG
318 debug_init();
319 #endif
320 /* Must be done before any code uses the multi-screen API */
321 gui_syncstatusbar_init(&statusbars);
322 storage_init();
323 settings_reset();
324 settings_load(SETTINGS_ALL);
325 gui_sync_wps_init();
326 sb_skin_init();
327 settings_apply(true);
328 init_dircache(true);
329 init_dircache(false);
330 #ifdef HAVE_TAGCACHE
331 init_tagcache();
332 #endif
333 sleep(HZ/2);
334 tree_mem_init();
335 filetype_init();
336 playlist_init();
338 #if CONFIG_CODEC != SWCODEC
339 mp3_init( global_settings.volume,
340 global_settings.bass,
341 global_settings.treble,
342 global_settings.balance,
343 global_settings.loudness,
344 global_settings.avc,
345 global_settings.channel_config,
346 global_settings.stereo_width,
347 global_settings.mdb_strength,
348 global_settings.mdb_harmonics,
349 global_settings.mdb_center,
350 global_settings.mdb_shape,
351 global_settings.mdb_enable,
352 global_settings.superbass);
354 /* audio_init must to know the size of voice buffer so init voice first */
355 talk_init();
356 #endif /* CONFIG_CODEC != SWCODEC */
358 scrobbler_init();
359 #if CONFIG_CODEC == SWCODEC
360 tdspeed_init();
361 #endif /* CONFIG_CODEC == SWCODEC */
363 audio_init();
364 button_clear_queue(); /* Empty the keyboard buffer */
367 #else
369 static void init(void)
371 int rc;
372 bool mounted = false;
373 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
374 /* if nobody initialized ATA before, I consider this a cold start */
375 bool coldstart = (PACR2 & 0x4000) != 0; /* starting from Flash */
376 #endif
378 system_init();
379 kernel_init();
381 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
382 set_cpu_frequency(CPUFREQ_NORMAL);
383 #ifdef CPU_COLDFIRE
384 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
385 #endif
386 cpu_boost(true);
387 #endif
389 buffer_init();
391 settings_reset();
393 i2c_init();
395 power_init();
397 enable_irq();
398 #ifdef CPU_ARM
399 enable_fiq();
400 #endif
401 lcd_init();
402 #ifdef HAVE_REMOTE_LCD
403 lcd_remote_init();
404 #endif
405 font_init();
407 show_logo();
408 lang_init(core_language_builtin, language_strings,
409 LANG_LAST_INDEX_IN_ARRAY);
411 #ifdef DEBUG
412 debug_init();
413 #else
414 #ifdef HAVE_SERIAL
415 serial_setup();
416 #endif
417 #endif
419 #if CONFIG_RTC
420 rtc_init();
421 #endif
422 #ifdef HAVE_RTC_RAM
423 settings_load(SETTINGS_RTC); /* early load parts of global_settings */
424 #endif
426 adc_init();
428 usb_init();
429 #if CONFIG_USBOTG == USBOTG_ISP1362
430 isp1362_init();
431 #elif CONFIG_USBOTG == USBOTG_M5636
432 m5636_init();
433 #endif
435 backlight_init();
437 button_init();
439 powermgmt_init();
441 #if CONFIG_TUNER
442 radio_init();
443 #endif
445 /* Must be done before any code uses the multi-screen API */
446 gui_syncstatusbar_init(&statusbars);
448 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
449 /* charger_inserted() can't be used here because power_thread()
450 hasn't checked power_input_status() yet */
451 if (coldstart && (power_input_status() & POWER_INPUT_MAIN_CHARGER)
452 && !global_settings.car_adapter_mode
453 #ifdef ATA_POWER_PLAYERSTYLE
454 && !ide_powered() /* relies on probing result from bootloader */
455 #endif
458 rc = charging_screen(); /* display a "charging" screen */
459 if (rc == 1) /* charger removed */
460 power_off();
461 /* "On" pressed or USB connected: proceed */
462 show_logo(); /* again, to provide better visual feedback */
464 #endif
466 rc = storage_init();
467 if(rc)
469 #ifdef HAVE_LCD_BITMAP
470 lcd_clear_display();
471 lcd_putsf(0, 1, "ATA error: %d", rc);
472 lcd_puts(0, 3, "Press ON to debug");
473 lcd_update();
474 while(!(button_get(true) & BUTTON_REL)); /*DO NOT CHANGE TO ACTION SYSTEM */
475 dbg_ports();
476 #endif
477 panicf("ata: %d", rc);
480 #ifdef HAVE_EEPROM_SETTINGS
481 eeprom_settings_init();
482 #endif
484 #ifndef HAVE_USBSTACK
485 usb_start_monitoring();
486 while (usb_detect() == USB_INSERTED)
488 #ifdef HAVE_EEPROM_SETTINGS
489 firmware_settings.disk_clean = false;
490 #endif
491 /* enter USB mode early, before trying to mount */
492 if (button_get_w_tmo(HZ/10) == SYS_USB_CONNECTED)
493 #if (CONFIG_STORAGE & STORAGE_MMC)
494 if (!mmc_touched() ||
495 (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED))
496 #endif
498 gui_usb_screen_run();
499 mounted = true; /* mounting done @ end of USB mode */
501 #ifdef HAVE_USB_POWER
502 if (usb_powered()) /* avoid deadlock */
503 break;
504 #endif
506 #endif
508 if (!mounted)
510 rc = disk_mount_all();
511 if (rc<=0)
513 lcd_clear_display();
514 lcd_puts(0, 0, "No partition");
515 lcd_puts(0, 1, "found.");
516 #ifdef HAVE_LCD_BITMAP
517 lcd_puts(0, 2, "Insert USB cable");
518 lcd_puts(0, 3, "and fix it.");
519 #endif
520 lcd_update();
522 while(button_get(true) != SYS_USB_CONNECTED) {};
523 gui_usb_screen_run();
524 system_reboot();
528 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
529 (CONFIG_KEYPAD == IRIVER_H10_PAD)
530 #ifdef SETTINGS_RESET
531 /* Reset settings if holding the reset button. (Rec on Archos,
532 A on Gigabeat) */
533 if ((button_status() & SETTINGS_RESET) == SETTINGS_RESET)
534 #else
535 /* Reset settings if the hold button is turned on */
536 if (button_hold())
537 #endif
539 splash(HZ*2, str(LANG_RESET_DONE_CLEAR));
540 settings_reset();
542 else
543 #endif
544 settings_load(SETTINGS_ALL);
546 if (init_dircache(true) < 0)
548 #ifdef HAVE_TAGCACHE
549 remove(TAGCACHE_STATEFILE);
550 #endif
553 gui_sync_wps_init();
554 sb_skin_init();
555 settings_apply(true);
556 init_dircache(false);
557 #ifdef HAVE_TAGCACHE
558 init_tagcache();
559 #endif
561 #ifdef HAVE_EEPROM_SETTINGS
562 if (firmware_settings.initialized)
564 /* In case we crash. */
565 firmware_settings.disk_clean = false;
566 eeprom_settings_store();
568 #endif
569 playlist_init();
570 tree_mem_init();
571 filetype_init();
572 scrobbler_init();
573 #if CONFIG_CODEC == SWCODEC
574 tdspeed_init();
575 #endif /* CONFIG_CODEC == SWCODEC */
577 #if CONFIG_CODEC != SWCODEC
578 /* No buffer allocation (see buffer.c) may take place after the call to
579 audio_init() since the mpeg thread takes the rest of the buffer space */
580 mp3_init( global_settings.volume,
581 global_settings.bass,
582 global_settings.treble,
583 global_settings.balance,
584 global_settings.loudness,
585 global_settings.avc,
586 global_settings.channel_config,
587 global_settings.stereo_width,
588 global_settings.mdb_strength,
589 global_settings.mdb_harmonics,
590 global_settings.mdb_center,
591 global_settings.mdb_shape,
592 global_settings.mdb_enable,
593 global_settings.superbass);
595 /* audio_init must to know the size of voice buffer so init voice first */
596 talk_init();
597 #endif /* CONFIG_CODEC != SWCODEC */
599 audio_init();
601 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
602 pcm_rec_init();
603 #endif
605 /* runtime database has to be initialized after audio_init() */
606 cpu_boost(false);
608 #if CONFIG_CHARGING
609 car_adapter_mode_init();
610 #endif
611 #ifdef IPOD_ACCESSORY_PROTOCOL
612 iap_setup(global_settings.serial_bitrate);
613 #endif
614 #ifdef HAVE_ACCESSORY_SUPPLY
615 accessory_supply_set(global_settings.accessory_supply);
616 #endif
619 #ifdef CPU_PP
620 void cop_main(void)
622 /* This is the entry point for the coprocessor
623 Anyone not running an upgraded bootloader will never reach this point,
624 so it should not be assumed that the coprocessor be usable even on
625 platforms which support it.
627 A kernel thread is initially setup on the coprocessor and immediately
628 destroyed for purposes of continuity. The cop sits idle until at least
629 one thread exists on it. */
631 /* 3G doesn't have Rolo or dual core support yet */
632 #if NUM_CORES > 1
633 system_init();
634 kernel_init();
635 /* This should never be reached */
636 #endif
637 while(1) {
638 sleep_core(COP);
641 #endif /* CPU_PP */
643 int main(void)
645 app_main();
647 while(1) {
648 #if (CONFIG_LED == LED_REAL)
649 led(true); sleep(HZ/10);
650 led(false); sleep(HZ/10);
651 #endif
653 return 0;
655 #endif